【发布时间】:2018-04-17 13:01:36
【问题描述】:
UPD:问题What is the reason JavaScript setTimeout is so inaccurate? 询问为什么JavaScript 中的计时器通常不准确,并且所有提到的不准确都是关于在指定延迟之后稍稍的调用。在这里,我问为什么 NodeJS 甚至在延迟之前也容忍调用?定时器的设计不是容易出错吗?
刚刚发现 NodeJS setTimeout() 的意外行为(仅对我而言?)。有时它会比指定的延迟更早触发。
function main() {
let count = 100;
while (count--) {
const start = process.hrtime();
const delay = Math.floor(Math.random() * 1000);
setTimeout(() => {
const end = process.hrtime(start);
const elapsed = (end[0] * 1000 + end[1]/1e6);
const dt = elapsed - delay;
if (dt < 0) {
console.log('triggered before delay', delay, dt);
}
}, delay);
}
}
main();
在我的笔记本电脑上的输出是:
$ node --version
$ v8.7.0
$ node test.js
triggered before delay 73 -0.156439000000006
triggered before delay 364 -0.028260999999986325
triggered before delay 408 -0.1185689999999795
triggered before delay 598 -0.19596799999999348
triggered before delay 750 -0.351709000000028
它是事件循环的“特性”吗?我一直认为至少要在delayms之后触发。
【问题讨论】:
-
我已经复制了这个问题。我试图将
setTimeout(...)放在IIFE 中,就像(function(start, delay) { ... })(start, delay);一样,它似乎减少了在预期之前触发的事件数量。但我仍然没有解释。 -
延迟时间只有几分之一毫秒。我认为这与您将获得的一样好。
-
为什么会被否决?这个问题是完全有效的。我刚刚遇到了一个损坏的测试用例,因为它预计超时为至少指定的毫秒数。一开始我并没有意识到这个错误。
标签: javascript node.js settimeout event-loop