Nodejs event loop

in 编程
关注公众号【好便宜】( ID:haopianyi222 ),领红包啦~
阿里云,国内最大的云服务商,注册就送数千元优惠券:https://t.cn/AiQe5A0g
腾讯云,良心云,价格优惠: https://t.cn/AieHwwKl
搬瓦工,CN2 GIA 优质线路,搭梯子、海外建站推荐: https://t.cn/AieHwfX9

node 执行完主线程中的同步任务时, 它会检查是否有等待中的异步操作, 如果有,则会开始事件循环, 否则它会退出.

事件循环的 6 个阶段

这些异步操作, 可在入口脚本中被添加至指定的模块(eg. 定时器模块), eg:

//entry.js

console.log(1);
//异步操作, 就绪时, 其回调被添加进 timer 队列中
setTimeout(()=>console.log('timeout callback'),0);
console.log(2);
//异步操作, 其回调被添加进 check 队列中
setImmediate(()=>console.log('immediate callback'));
console.log(3);

当某个异步操作被就绪时(eg. 定时器到达指定时间), 该异步操作的回调就会被添加到相应阶段的队列中(eg. 定时器的回调被添加到 timer 阶段的队列中),等待被执行.

执行顺序

node 按照上图的顺序执行每个阶段的队列, 当队列为空时, 它会转入下一阶段. 当执行 poll 阶段时, 它按照以下逻辑执行:

poll 执行完其队列后, 会检查是否有定时器就绪, 如果有, 则会结束 poll 阶段, 继续本轮循环的执行, 然后进入下一轮循环中执行就绪的定时器.

setTimeout 与 setImmediate

当在非 I/O 周期中执行 setTimeoutsetImmediate 时, 其顺序依赖于当前系统的环境. 如果系统运行到事件循环开始, 超过了定时器设定的时间( setTimeout 的第二个参数默认值为 0, 但是 node 达不到 0ms 就执行定时器的要求, 实际值从 1ms 开始), 则 setTimeout 先于 setImmediate 被执行, 反之 setImmediate 先于 setTimeout.

setTimeout(()=>console.log('timeout'),0);
setImmediate(()=>console.log('immediate'));
//output: 1 2 or 2 1

当在 I/O 周期中执行时, setImmediate 先于 setTimeout 执行. 因为执行 I/O 操作时为 poll 阶段, poll 阶段结束后, 就转入了 check 阶段.

const fs = require('fs');
fs.readFile(__filename,()=>{
    setTimeout(()=>console.log('timeout'),0);
    setImmediate(()=>console.log('immediate'));
})
//output: immediate timeout

process.nextTick

process.nextTick 在所有同步操作执行完毕之后、事件循环开始之前执行、每个阶段执行之前执行

setTimeout(()=>console.log('timeout'),0);
process.nextTick(()=>console.log('nextTick'));
console.log('entry');
//output: entry nextTick timeout
setTimeout(()=>{
    console.log('timeout1');
    process.nextTick(()=>console.log('nextTick'));
},0);
setTimeout(()=>console.log('timeout2'));
//output: timeout1 timeout2 nextTick
setTimeout(()=>{
    console.log('wrap-timeout');
    setTimeout(()=>console.log('inner-timeout'),0);
    process.nextTick(()=>{
        console.log('wrap-nextTick');
        process.nextTick(()=>console.log('inner-nextTick'));
    });
},0);
//output: wrap-timeout wrap-nextTick inner-nextTick inner-timeout
关注公众号【好便宜】( ID:haopianyi222 ),领红包啦~
阿里云,国内最大的云服务商,注册就送数千元优惠券:https://t.cn/AiQe5A0g
腾讯云,良心云,价格优惠: https://t.cn/AieHwwKl
搬瓦工,CN2 GIA 优质线路,搭梯子、海外建站推荐: https://t.cn/AieHwfX9
扫一扫关注公众号添加购物返利助手,领红包
Comments are closed.

推荐使用阿里云服务器

超多优惠券

服务器最低一折,一年不到100!

朕已阅去看看