gpt4 book ai didi

javascript - `setImmediate()` 和 `setTimeout()` 的计时如何受进程性能的约束?

转载 作者:行者123 更新时间:2023-12-05 02:27:55 26 4
gpt4 key购买 nike

我对 Node.js 文档的以下段落感到困惑。

setImmediate() vs setTimeout()

... The order in which the timers are executed will vary depending on the context in which they are called. If both are called from within the main module, then timing will be bound by the performance of the process (which can be impacted by other applications running on the machine).

For example, if we run the following script which is not within an I/O cycle (i.e. the main module), the order in which the two timers are executed is non-deterministic, as it is bound by the performance of the process:

它继续显示以下示例

// timeout_vs_immediate.js
setTimeout(() => {
console.log('timeout');
}, 0);

setImmediate(() => {
console.log('immediate');
});
$ node timeout_vs_immediate.js
timeout
immediate

$ node timeout_vs_immediate.js
immediate
timeout

我不明白是什么导致结果不确定。由于 timers 阶段发生在 check 阶段之前,由 setTimeout 安排的回调不应该总是在由 setImmediate< 安排的回调之前执行吗?我不认为事件循环中的阶段顺序会因上下文切换或其他原因而改变。

文档还指出

However, if you move the two calls within an I/O cycle, the immediate callback is always executed first:

好的,但是什么使所谓的“I/O 周期”与主模块不同?


我知道有很多相关问题,但所有答案都只是通过引用文档来说明这一事实,而没有解释非确定性在何处发挥作用,因此我认为这不是重复。

最佳答案

真正的技巧在 Timeout constructor 中这是由 setTimeout 调用的,它将低于 1 的时间增加到 1。因此 setTimeout(fn, 0) 实际上等同于 setTimeout(fn, 1).

libuv initializes ,它在更新其内部时钟后从计时器开始,当一毫秒已经过去时,它会在进入轮询阶段(随后是 setImmediate 阶段)之前拾取计时器。


另一个有趣的观察是,多个计时器也可能在 setImmeadiate 之前 之前运行:

setTimeout(() => console.log('timer'), 1);
setTimeout(() => console.log('timer'), 1);
setImmediate(() => console.log('immediate'));
// can produce:
// timer
// immediate
// timer

那是因为setTimeout在内部调用了getLibuvNow,会调用env->GetNow(),不仅获取了libuv的当前时间, 但是 also updates it .因此,定时器可能会以不同的到期时间被放入定时器队列,因此定时器阶段只会选择其中的一些。

OK, but what makes so-called "I/O cycles" different from the main module?

主模块在 libuv 初始化之前运行,而大多数其他代码将在 libuv looppoll 阶段运行。 .因此,主模块初始化之后是计时器阶段,而轮询阶段之后是“检查句柄”阶段,其中运行 setImmediate 回调。因此通常在主模块中,定时器会在立即数之前运行(如果它们到期的话),如果在回调中安排,立即数会在定时器之前运行。

关于javascript - `setImmediate()` 和 `setTimeout()` 的计时如何受进程性能的约束?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72834122/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com