我们知道,Node.js 的最大亮点,就是单线程的异步非阻塞 I/O。而实现这个机制的,就是事件循环。
在 js 核心部分,我记录过浏览器的事件循环,从这里回顾。
Node.js 与浏览器的事件循环原理基本相似,但是运行机制不同。
首先附上一张简化的 Node.js 架构图:
Node 整体上由这三部分组成:
V8:JS 的运行引擎,它负责把 JavaScript 代码转换成 C++
libuv:封装异步 I/O 能力,初始化事件循环
浏览器的 Event-Loop 由各个浏览器自己实现;而 Node 的 Event-Loop 由 libuv 来实现。
共六个阶段,有不同的任务:
上述的 6 个阶段中,需要重点关注的是 3 个阶段:
timers、poll 和 check
面试题一般出在这三个阶段。
事件循环流程如下:
浏览器宏任务 “一个一个” 地执行,Node 浏览器 “一队一队” 地执行.
setImmediate
和 process.nextTick
这两个函数只在 Node 中有,浏览器是没有的。
process.nextTick 是将一个任务放到微任务队列:
process.nextTick(() => {// ...我在微任务队列});
setImmediate 是将一个任务放到宏任务队列:
setImmediate(() => {// ...我在宏任务队列});
延迟 0 毫秒的 setTimeout() 回调与 setImmediate() 非常相似,都在宏任务队列中,执行顺序取决于各种因素,不固定。