问题描述
// timeout_vs_immediate.js
setTimeout(() => {
console.log('timeout');
}, 0);
setImmediate(() => {
console.log('immediate');
});
根据文档:
例如,如果我们运行以下不在 I/O 中的脚本循环(即主模块),两个定时器的顺序执行是不确定的,因为它受过程.
为什么上面的说法是正确的?是不是因为 nodejs 运行时实际上使用了多个线程来挑选必须执行的回调.
Why is the above statement true ? Is it because the nodejs runtime actually employs more than one thread to pick out the callbacks that have to be executed.
我的直觉是:有两个线程为 setTimeout
和 setImmediate
执行回调,所以当它们都可用时,这会导致竞争条件,因此输出将是不确定的.
What my intuition says: there are two threads that execute callbacks for setTimeout
and setImmediate
so when both of them are available this leads to a race condition, and thus the output will be non-deterministic.
正确吗?或者是否有其他原因导致这是不确定的?
Is it correct ? Or is there any other reason for which this is non-deterministic ?
推荐答案
本质上,发生了两件事:
Essentially, two things happen:
- setTimer(0..) 被转换成 setTimer(1..)
在(下一个)事件循环开始之前,node/libuv 必须执行clock_gettime() 以从系统获取当前时间.此系统调用所用的时间是不确定的,因为它取决于当时的系统负载.现在,如果 clock_gettime() 花费的时间超过 1ms,则 setTimer 回调将运行 (#),否则事件循环将继续到下一阶段 (##).
- setTimer(0..) gets converted into setTimer(1..)
before the (next) event loop tick begins, node/libuv has to perform a clock_gettime() to get the current time from the system. The time taken for this system call is non deterministic as it depends on the system load at that time. Now, if clock_gettime() took more than 1ms, the setTimer callback will run (#), else event loop continues to next phase (##).
- 如果 (#),setTimeout(0,..) 回调在 setImmediate() 之前运行
- 如果 (##),则不然.
参考:https://github.com/nodejs/help/issues/392#issuecomment-305969168
这篇关于为什么在主模块中使用时 setTimeout(0) 和 setImmediate() 的行为未定义?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!