Node 与浏览器 EventLoop 的差异

事件循环

1
事件循环是计算机系统的一种运行机制,JavaScript 采用事件循环机制来处理异步任务的执行。

HTML规范 中指出:一个事件循环有一个或者多个任务队列(Task Queue),一个任务队列有一组任务(异步任务)

任务可以分成两种,一种是同步任务,另一种是异步任务

1
执行栈中的同步任务执行完毕后,才会将事件队列中的异步任务加入到主线程执行。

同步任务形成 执行栈,是指在主线程上排队执行的任务。

异步任务不进入主线程排队,而是进入 Task Queue 排队的任务,只有 Task Queue 通知主线程,某个异步任务可以执行了,该任务才会进入主线程执行。

异步任务分为:宏任务(macrotask)微任务(microtask)

  • 宏任务(macrotask):
    包含执行整体的 JavaScript 代码、事件回调、XHR 回调、定时器(setTimeout/setInterval/setImmediate)、IO操作以及UI渲染。

  • 微任务(microtask):
    更新应用程序状态的任务,包括 promise 回调、MutationObserverprocess.nextTick 以及 Object.observe

event-loop

Node.js 中的事件循环

node.js 运行时,会初始化一个 EventLoop,处理那些通过异步api调用定时器或者调用 process.nextTick() 提供的 script或者输入到 REPL 中的 script

下图展示了事件循环的操作顺序以及概要。

node事件循环

浏览器中的事件循环

一个宏任务可能包含多个微任务。

  • 执行一个宏任务(macrotask)

  • 执行过程中如果遇到微任务(microtask),就将它添加到微任务的任务队列中。

  • 宏任务(macrotask)执行完毕后,立即执行当前微任务(microtask)队列中的所有微任务(先进先出)。

  • 重复上述三个步骤,当所有任务执行完毕,开始检查渲染,然后 GUI 线程接管渲染。

浏览器事件循环

差异

Node.js 中,微任务 microtask 会在事件循环的各个阶段之间执行,也就是一个阶段执行完毕,就会去执行 microtask 队列的任务。

node事件循环

浏览器环境下,微任务 microtask 队列是在每个宏任务 macrotask 执行完之后执行。

浏览器事件循环