vlambda博客
学习文章列表

6月第13题:浏览器与Node的事件循环(Event Loop)有何区别?


浏览器和 Node 环境下,microtask 任务队列的执行时机不同

  • Node 端,microtask 在事件循环的各个阶段之间执行

  • 浏览器端,microtask 在事件循环的 macrotask 执行完之后执行


【扩展】
  • Node.js 采用 V8 作为 js 的解析引擎,而 I/O 处理方面使用了自己设计的 libuv,libuv 是一个基于事件驱动的跨平台抽象层,封装了不同操作系统一些底层特性,对外提供统一的 API,事件循环机制也是它里面的实现

  • Node.js 的运行机制如下:

  • 1、V8 引擎解析 JavaScript 脚本。

  • 2、解析后的代码,调用 Node API。

  • 3、libuv 库负责 Node API 的执行。它将不同的任务分配给不同的线程,形成一个 Event Loop(事件循环),以异步的方式将任务的执行结果返回给 V8 引擎。

  • 4、V8 引擎再将结果返回给用户。


  • libuv 引擎中的事件循环分为 6 个阶段,它们会按照顺序反复运行。每当进入某一个阶段的时候,都会从对应的回调队列中取出函数去执行。当队列为空或者执行的回调函数数量到达系统设定的阈值,就会进入下一阶段。
  • 1、timers 阶段:这个阶段执行 timer(setTimeout、setInterval)的回调

  • 2、I/O callbacks 阶段:处理一些上一轮循环中的少数未执行的 I/O 回调

  • 3、idle, prepare 阶段:仅 node 内部使用

  • 4、poll 阶段:获取新的 I/O 事件, 适当的条件下 node 将阻塞在这里

  • 5、check 阶段:执行 setImmediate() 的回调

  • 6、close callbacks 阶段:执行 socket 的 close 事件回调