NodeJs的Event Loop

释放双眼,带上耳机,听听看~!

我们之前谈过浏览器的Event Loop:https://www.cnblogs.com/amiezhang/p/11349450.html

简单来说,就是每执行一个宏任务,就去执行微任务队列,直到清空,再执行下个宏任务。

那么NodeJs的Event Loop是怎么样的呢?

 

NodeJS的Event Loop

NodeJs的Event Loop其实也分了宏任务和微任务

不同的是,不是每执行一个宏任务就回去清空一次微任务队列,可能是连着执行好几个才去清空一次微任务队列。

例子:


1
2
3
4
5
6
1setTimeout(()=>{
2    console.log(1);
3    new Promise(resolve=>resolve()).then(()=>console.log(3))
4})
5setTimeout(()=>{console.log(2)})
6

同一个例子,在浏览器和Node环境下,输出不一致。

浏览器:

NodeJs的Event Loop

NodeJs:

NodeJs的Event Loop

可以看出:

浏览器在执行第一个 setTimeout 宏任务时,往微任务队列推了一个 console.log(3 ),所以在执行完第一个setTimeout后,浏览器的 Event Loop 机制马上去执行微任务队列,然后再执行下个setTimeout宏任务

NodeJs 在执行第一个 setTimeout 宏任务时,也往微任务队列推了一个 console.log(3),但是NodeJs的 Event Loop 机制却继续去执行下个 setTimeout 宏任务,等2个 setTimeout 宏任务都执行完后,才去执行微任务队列。

宏任务和微任务的执行机制图

图中 Tick 就是执行清空微任务的时机,我们可以看到 NodeJs 的 Event Loop 分为 5 个阶段,在每个阶段间会执行清空一次微任务队列。

所以不难理解,在上面的例子,Times 阶段有 2 个宏任务,所以,console.log(2) 需要等整个 Times 阶段走完,才能得以执行。

 NodeJs的Event Loop

NodeJs 各个执行阶段

timers

从技术上来说,poll阶段控制timers什么时候执行,而执行的具体位置在timers。

I/O callbacks

idle, prepare

poll

  • poll队列不为空的时候,事件循环肯定是先遍历队列并同步执行回调,直到队列清空或执行回调数达到系统上限。
    • 如果代码已经被setImmediate()设定了回调,那么事件循环直接结束poll阶段进入check阶段来执行check队列里的回调。
        • 如果有被设定的timers,那么此时事件循环会检查timers,如果有一个或多个timers下限时间已经到达,那么事件循环将绕回timers阶段,并执行timers的有效回调队列。
          • 如果没有被设定timers,这个时候事件循环是阻塞在poll阶段等待回调被加入poll队列。

check

close callbacks

关于setTimeout和setImmediate


1
2
3
4
5
6
7
1setTimeout(() => {
2    console.log('setTimeout');
3}, 0); // 当 delay 设置为 0 的时候,NodeJs 会设置为 1ms,因为最小是 1ms
4setImmediate(() => {
5    console.log('setImmediate');
6})
7

给TA打赏
共{{data.count}}人
人已打赏
安全技术

【JWT】JWT+HA256加密 Token验证

2021-8-18 16:36:11

安全技术

C++ 高性能服务器网络框架设计细节

2022-1-11 12:36:11

个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索