我需要每1秒生成一个事件。我正在测试setTimeout函数如下:
window.onload = function() {
var oldTime = Date.now();
setTimeout(function printTime() {
newTime = Date.now();
console.log(newTime - oldTime);
oldTime = newTime;
setTimeout(printTime, 1000);
}, 1000);
}
它返回1s并略微偏移:
testTimeout.js:6 1005
testTimeout.js:6 1006
2testTimeout.js:6 1001
testTimeout.js:6 1006
testTimeout.js:6 1005
testTimeout.js:6 1006
testTimeout.js:6 1005
抵消来自哪里?是因为oldTime和newTime计算?
答案 0 :(得分:3)
我需要每隔1秒生成一个事件。
没有办法以精确的精确度做到这一点。
传递给setTimeout
的时间是代码运行的最短保证时间,而不是确切的时间。
时间表示JS引擎将该函数推送到Event Queue的毫秒数。一旦该功能在事件队列中,在队列中存在的所有当前任务之后运行,例如事件和其他计时器,这将产生延迟。
此外,在运行任何常规JS代码时,无法从事件队列执行任务,这也可能会造成很小的延迟。
例如,此函数test
:
setTimeout(function test() {
console.log('second');
}, 0);
for (i = 0; i < 1000000; i++); // the number 1000000 is an arbitrary big number
console.log('first');
&#13;
将在完成下面的循环后运行,这将超过0
毫秒。
实际上,如果该循环是无限的,那么setTimeout
回调将永远不会触发。
注意:正如评论中 nnnnnn 所述,setTimeout
推送功能的实际最短时间per the HTML5 spec对于事件队列是4毫秒,无论我们放少。以前这个限制曾经是10ms。
实际上,HTML5规范指定了4毫秒,并且在2010年及之后发布的浏览器中保持一致。在(Firefox 5.0 / Thunderbird 5.0 / SeaMonkey 2.2)之前,嵌套超时的最小超时值为10毫秒。