2

在官方文档“setImmediate() vs setTimeout()”部分中,它说:“setImmediate() 旨在在当前轮询阶段完成后执行脚本”,据我了解,这也意味着当前滴答/事件循环循环。

然而,稍后在“process.nextTick() 与 setImmediate()”部分中,它说:“setImmediate()在事件循环的以下迭代或‘tick’上触发”。

那么哪一个是正确的答案,我在这里错过了什么吗?

提前致谢。

文档相关页面:https ://nodejs.org/en/docs/guides/event-loop-timers-and-nexttick/

4

2 回答 2

0

简单的回答:

setImmediate在下一个刻度上运行。

细节:

setImmediate并且setTimeout都在事件循环的不同阶段运行。

这就是为什么当setTimeout设置为零延迟时它不会立即运行。使用 setImmediate 它总是在事件循环的下一个滴答声中运行。

process.nextTick基本上不关心事件循环的阶段。您分配给此方法的回调将在当前操作完成后和事件循环继续之前执行。

您链接的文档对差异有很好的解释。我将在这里吸引您的注意力。在setimmediate-vs-settimeout中,调用顺序是不确定的,除非它们被安排在 I/O 周期内,如下例所示。

现在添加process.nextTick到示例中

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

process.nextTick(() => {
  console.log('nextTick')
})

输出:

nextTick
immediate
timeout

如果您运行上面的代码,process.nextTick函数中的任何内容都将首先执行。原因是,它在事件循环继续之前运行。请记住,两者都setTimeoutsetImmediate事件循环相关,但与 process.nextTick 无关。

要非常小心你如何使用process.nextTick. 如果你没有正确使用它,你最终可能会陷入糟糕的境地。

于 2021-10-20T17:40:48.480 回答
0

感谢您加入 Stack Overflow!,我必须说您的问题非常好!


如下图所示: 事件循环圈

该图来自事件循环和大图 — NodeJS 事件循环第 1 部分 作者 Deepal Jayasekara

“圆圈周围的方框说明了我们之前看到的不同阶段的队列,中间的两个方框说明了在从一个阶段移动到另一个阶段之前需要耗尽的两个特殊队列。“下一个滴答队列”处理回调通过 nextTick() 注册,..."

来自Synk - Node.js Event-Loop:即使是快速的 Node.js 异步函数也可以阻止 Event-Loop,饿死 I/O,参考上面的文章


所以和之间setTimeout的区别是:setImmediatenextTick

  • setTimeout安排一个脚本在经过以毫秒为单位的最小阈值后运行。1
  • setImmediate在 poll 阶段之后运行(pool 阶段就是图中的 IO 事件队列)
  • nextTick在阶段之间运行。

1定时器的执行顺序将根据调用它们的上下文而有所不同。有关更多信息,请参见此处

于 2021-10-20T16:40:31.793 回答