Nodejs 事件循环 - 与顶级代码交互

2023-12-28

hoping for a little confirmation on understanding of node.js execution model. I understand that when node.js process starts, this is the sequence of executions: enter image description here (from Jonas Schmedtmann's Udemy node.js course)

主要要点是顶层代码总是先执行any回调。

Then, in the event-loop, this is the sequence of the 'phases': enter image description here

经过一番挖掘,我还确认了为什么在主模块中调用的 setTimeout 和 setImmediate 具有“任意”执行顺序,但是当从 I/O 阶段调用时,setImmediate 将始终首先执行,基于这篇文章:https://github.com/nodejs/help/issues/392#issuecomment-274032320 https://github.com/nodejs/help/issues/392#issuecomment-274032320.

(原因:假设定时器阈值已经过去,因为我们当前处于 I/O 阶段,之后的下一个阶段是执行 setImmediate 回调的检查处理阶段,立即执行总是在定时器之前执行。)

现在,当从一个阶段调用计时器和立即回调时,使得下一个阶段是到期计时器阶段(例如从主模块),如果顶级代码花费了足够长的时间以致计时器到期,则计时器回调将总是先执行,对吗?我已经用下面的代码对此进行了测试,它似乎是正确的(每次运行它时,计时器都会首先执行,即使与立即回调相比它有整整一秒的延迟)

setTimeout(() => {
  console.log('timer completed');
}, 1000);

setImmediate(() => {
  console.log('immediate completed');
});

for (let i = 0; i < 5000; i++) {
  console.log(`top-level code: ${i}`);
}

所以这是我的问题:由于事件循环,假设顶级代码需要足够长的时间以便 I/O 操作在我们完成时完成,那么 I/O 操作回调不应该在立即回调之前执行吗?启动事件循环?

但是,下面的代码表明不然,因为执行顺序始终是:top-levels->timer->immediate->io

即使基于上面的模型,我应该期待:顶级 - >计时器 - > io - >立即(?)

setTimeout(() => {
  console.log('timer completed');
}, 1000);

fs.readFile('test-file.txt', 'utf-8', () => {
  console.log('io completed');
});

setImmediate(() => {
  console.log('immediate completed');
});

for (let i = 0; i < 5000; i++) {
  console.log(`top-level code: ${i}`);
}

谢谢你!


我回答这个问题可能有点晚了,你可能已经弄清楚了这个问题@M.Lee。但这是你问题的答案:

在顶级代码执行期间,您在示例中运行的代码不在事件循环中运行。就像您的问题中的第一张图片所示,事件循环将在顶级代码执行完毕后开始计时。因此,当涉及到顶级代码时,Node 不会遵循事件循环周期期间所遵循的相同顺序。

在这种特殊情况下,I/O 回调最后执行显然是因为该特定文件的内容 (顺便说一句,我必须继续研究 Jonas 的 Node 课程并了解该文件包含的内容。它只包含一行“Node.js 是最好的!” 100万次).

这里还有一个注意事项是您正在使用异步readFile函数而不是readFileSync.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Nodejs 事件循环 - 与顶级代码交互 的相关文章

随机推荐