今天下班前,偶然听到后端一实习小伙子说要把一东西改成异步因为太耗时,由于他们前几天又说的是多线程。我一个前端小白就思考了,多线程和异步是一个东西吗?异步一定是多线程的吗?如果是,那为什么我们前端的JavaScript 既是单线程又可以是异步的呢?异步ajax又是怎么回事?不知道是否有人跟我有一样的疑问,我写这篇文章自问自答一下。
多线程和异步是一个东西吗?
答案是否定的,异步是目的,多线程只是模拟实现异步的手段而已。只不过他们后端写java的常常用多线程来实现异步。
比如现在有 A、B、C、D 四个函数,我希望在执行 A 的同时执行 B,并且执行完 A 之后执行 C,执行完 B 之后执行 D。那么,A、B 之间是异步的,我们可以分别在两个线程T1、T2上去执行它们,而在各自的线程上,A、C之间是同步的,B、D之间是同步的。这里的AB相互不干扰就称之为异步,而且是用多线程所实现的。
实现异步一定是多线程的吗?
想必你心中已经有答案了,既然异步只是一个目的而已,多线程肯定不是实现它的唯一方法了。
为什么说前端的JavaScript 是单线程又可以做异步操作?
实际上,说js是单线程的不是一个很严谨的说法,Js的执行是单线程,而浏览器是多线程的。比如,浏览器端的 Javascript 实现了两个很重要的异步 API,它们分别是 定时器 和 AJAX请求。
定时器比如 setTimeout 被执行时,由浏览器的定时器线程执行的定时计数,而并不是 Javascript 执行线程负责计数,可以想象如果是 Javascript 执行线程负责计数,那必定会造成执行线程的阻塞。定时器线程在定时时间触发延时事件并将延时事件推入 Javascript 事件队列。当 Javascript 主线程同步代码执行完毕时,会去轮询该事件队列,取出最开始事件的处理函数推入主线程中被执行。
AJAX 请求和定时器类似,同样是委托浏览器线程代为执行耗时任务,这里是借由浏览器的HTTP请求线程发起对服务器的请求,在请求得到响应之后触发请求完成事件,将回调函数推入事件队列等待执行。