每秒奇怪的结果测试操作

时间:2018-11-21 12:34:49

标签: node.js performance event-loop

我正在此测试脚本的节点8.11上运行:

let end = false;

let i = 0;
setInterval(() => { i++; }).unref();


let k = 0;
async function loop() {
  k++
  if (end === false)
    setImmediate(loop);
}

console.time('test');
loop()
  .then(() => {
    setTimeout(() => {
      end = true;
      console.log('interval', i);
      console.log('recursion', k);
      console.timeEnd('test');
    }, 1000);
  })

输出为:

interval 997
recursion 824687
test: 1001.831ms

但是,如果我评论这两行:

  // if (end === false)
  //  setImmediate(loop);

结果是:

interval 537
recursion 1
test: 1003.882ms

我对phases of nodejs进行了艰苦的研究,但我不明白为什么setImmediate应该影响间隔函数的结果。

您有一些解释吗?

谢谢

1 个答案:

答案 0 :(得分:1)

那是因为在节点js上的计时器就不是精确的,因为它们只是事件循环中的事件,因此他们无法确切知道何时触发它们,这就是为什么setTimeout表示它将至少在您提供的时间。

  

不能依赖设置的超时间隔来执行   在精确的毫秒数之后。这是因为其他   执行阻止或保留在事件循环中的代码将推动   执行超时返回。唯一的保证是超时   不会早于声明的超时间隔执行。

设置setInmediate时,您在事件循环中填充了许多中间事件,因此将超时事件推回队列。

请记住,事件循环周期的时间长短不一(确切),因此,即使您认为setInmediate不应影响计时器,您也要延长事件循环的时间长。

有趣的文章

https://nodejs.org/en/docs/guides/timers-in-node/

https://medium.com/the-node-js-collection/what-you-should-know-to-really-understand-the-node-js-event-loop-and-its-metrics-c4907b19da4c

编辑:正如您所指出的,在您的情况下相反,使用setInmediate时会有更多的迭代。在那种情况下,这可能与事件循环的速度取决于程序的负载是动态的有关。

相关问题