如何确保Node.js中setTimeout()的最小延迟?

时间:2018-09-30 09:00:49

标签: javascript node.js

问题直截了当。

例如我需要在至少50毫秒(而不是49.8毫秒)后执行一些代码。

// min-timeout.spec.js
const util = require('util');
const {performance} = require('perf_hooks');

const wait = util.promisify(setTimeout);

it.only('setTimeout() minimum delay', async() => {
  for (let i = 0; i < 10; i++) {
    const start = performance.now();
    await wait(50);
    const time = performance.now() - start;
    console.log('time:', time);
  }
});

输出:

time: 51.01539999991655
time: 50.70590000227094
time: 50.79270000010729
time: 50.22399900108576
time: 49.343199998140335
time: 50.81929999962449
time: 49.999699000269175
time: 49.83229999989271
time: 50.78200000151992
time: 50.010999999940395

为什么有时执行时间少于50毫秒?是否依赖系统?如何在Node.js中的setTimeout()处确保最小延迟?

系统信息:

Microsoft Windows [Version 10.0.17134.285]
node v8.11.2

2 个答案:

答案 0 :(得分:2)

我认为这是由于jack的不准确性。

答案 1 :(得分:1)

问题特定于事件循环内Node.js中的计时器调度方式。异步调度的setTimeout可能会提前一毫秒被触发,而平均延迟将等于或大于指定的延迟。

为了对此行为进行补偿,可能是:

const wait = delay => new Promise(resolve => setTimeout(resolve, ++delay));

如果需要延迟来测试异步代码,则可以使用计时器模拟来快速转发计时器。