三个概念,轻松理解Javascript中的事件循环(Event Loop)

107 阅读2分钟

什么是事件循环

事件循环是 Javascript 引擎实现异步操作的一种机制。

Javascript 引擎都是单线程的,任何时刻最多只能处理一个任务,所以这里的异步,只是宏观层面的“同时进行”,类似于操作系统层面的“并发”概念。

三个概念

主线程

Javascript 引擎是用来实现 ECMAScript 标准的,Node 中是 V8,Chrome 中也是 V8,Safari 中是JavaScript Core,Firefox 中是 SpiderMonkey。所有的引擎都是单线程的,这个单线程就是所谓的主线程,所有的任务都在主线程上执行

异步处理模块

引擎提供了多种异步处理模块,如定时器、网络请求、Promise、I/O、UI rendering 等。在代码中调用这些异步方法,相当于对这部分代码做了“异步”标记。引擎在解释运行这些代码时,会进行特殊处理,最终在主线程中执行。

任务队列

任务队列存放了异步任务的回调处理,按照先进先出的方式顺序执行。任务队列分为两类:宏任务队列和微任务队列。

  • 宏任务 macro tasks:script setTimeout setInterval setImmediate I/O UI rendering
  • 微任务 micro tasks:process.nextTick Promise Object.observer MutationObserver

事件循环的具体过程

引擎在解释运行一段代码时,同步任务被压入主线程执行,异步任务交由异步处理模块处理。当异步任务达到触发条件(比如计时器到时、网络请求返回),回调处理压入任务队列。当主线程同步任务全部执行结束后,从任务队列中取出回调函数执行。主线程不断检查是否有任务执行,没有的话就从任务队列中读取。

在浏览器环境中,主线程上执行任务的顺序是这样的:

  1. 执行同步任务直至线程清空
  2. 取出微任务队列中的任务执行直至清空
  3. 取出宏任务队列中一个任务执行

重复第二步和第三步。