【发布时间】:2020-10-08 14:23:59
【问题描述】:
我已经阅读了process.nextTick() 上的官方文档和许多其他博客,但我对某些主题有些困惑。
首先,写在process.nextTick()中的回调在下一次迭代开始之前执行。
其次,当在 I/O 周期内时,事件循环当前处于轮询阶段。在轮询阶段之后,事件循环移动到检查阶段,在该阶段执行setImmediate 方法中调用的任何回调。
现在在下面的代码中
const fs = require('fs');
function main() {
fs.readFile('./xy.txt', function(err, buff){
setTimeout(()=> console.log("timeout inside fs"),0);
setImmediate(()=> console.log("immediate inside fs"));
process.nextTick(()=>{console.log("process.nextTick")});
console.log("inside fs");
})
console.log("called inside main fn in first-iteration");
}
main();
console.log("called in first-iteration);
输出将是:
called inside main fn in first-iteration
called in first iteration
在此期间 fs fn 的回调将被注册,并且上述两行将得到控制台,因为入口脚本将在没有事件循环的情况下运行。现在事件循环的第一次迭代将从计时器阶段开始,因为没有计时器存在,它将移动到挂起阶段,然后到轮询阶段,其中有一个回调(fs fn 回调),事件循环开始执行 fs 回调,现在将注册 setTimeout 回调和 setImmediate 回调。之后,process.nextTick 回调将注册到 nextTickQueue 中,该回调将在下一次迭代或滴答(第二次迭代)中执行。现在轮询阶段结束后,我们在第三行记录了inside fs。
接下来,事件循环应该移动到检查阶段,其中存在setImmediate 回调并且应该记录immediate inside fs,之后事件循环应该移动到下一个阶段并且第一次迭代应该结束。在开始第二次迭代之前,应该记录process.nextTick,然后最后记录timeout inside fs。
因此最终输出为:
called inside main fn in first-iteration
called in first iteration
inside fs
immediate inside fs
process.nextTick
timeout inside fs
但结果却是:
called inside main fn in first-iteration
called in first iteration
inside fs
process.nextTick
immediate inside fs
timeout inside fs
在某处写到微任务(process.nextTick)在最高优先级上执行,因此事件循环将保留其所有执行并乍一看执行微任务。但如果也是这样,为什么inside fs 会在process.nextTick 之前得到安慰?
基本上,我很困惑,process.nextTick() 和各个阶段的事件循环流程是如何进行的?
【问题讨论】:
标签: javascript node.js event-loop