为什么在主模块中使用时,setTimeout(0)和setImmediate()的行为是不确定的?

时间:2017-08-29 08:36:00

标签: node.js race-condition event-loop

nodejs event loop documentation获取以下代码:

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

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

根据文件:

  

例如,如果我们运行以下不在I / O中的脚本   循环(即主模块),两个定时器的顺序   执行是非确定性的,因为它受到性能的约束   这个过程。

为什么上述陈述是真的?是因为nodejs运行时实际上使用了多个线程来挑选必须执行的回调。

我的直觉说:有两个线程为setTimeoutsetImmediate执行回调,所以当两个线程都可用时,这会导致竞争条件,因此输出将是非确定性的

这是对的吗?或者还有其他任何不确定性的原因吗?

1 个答案:

答案 0 :(得分:1)

本质上,会发生两件事:

  1. setTimer(0 ..)转换为setTimer(1 ..)
  2. (下一个)事件循环刻度开始之前,node / libuv必须执行clock_gettime()才能从系统获取当前时间。此系统调用所花费的时间是不确定的,因为它取决于当时的系统负载。现在,如果clock_gettime()花费的时间超过1毫秒,则setTimer回调将运行(#),否则事件循环将继续进行到下一个阶段(##)。

    • 如果(#),则在setImmediate()之前运行setTimeout(0,..)回调
    • 如果是(##),则相反。

参考: https://github.com/nodejs/help/issues/392#issuecomment-305969168