setInterval会漂移吗?

Den*_*gan 38 javascript setinterval

这真是一个非常简单的问题.如果我使用setInterval(something, 1000),我可以完全确定31天之后它会触发"某些东西" 60*60*24*31吗?或者是否存在所谓漂移的风险?

Pao*_*ino 33

简答:不,你不能确定.是的,它可以漂移.

答案很长:John Resig关于JavaScript时间准确性以及JavaScript定时器的工作原理.

从第二篇文章:

为了理解定时器如何在内部工作,需要探索一个重要概念:不能保证定时器延迟.由于浏览器中的所有JavaScript都在单个线程上执行,因此异步事件(例如鼠标单击和计时器)仅在执行中打开时运行.

这两篇文章(以及该网站上的任何内容)都是很好的阅读,所以有它.

  • 它会尝试,但如果在 10 毫秒后执行被另一个长时间运行的函数阻止,它将漂移。另一个(愚蠢的)示例:如果您每 10 ms 执行一次的函数需要 11 ms 来运行怎么办?第二个函数什么时候运行?我相信 20 毫秒后(10 毫秒开始会跳过) (2认同)

Bli*_*ixt 20

这是您可以在Firefox中运行的基准测试:

var start = +new Date();
var count = 0;
setInterval(function () {
    console.log((new Date() - start) % 1000,
    ++count,
    Math.round((new Date() - start)/1000))
}, 1000);
Run Code Online (Sandbox Code Playgroud)

第一个值应该尽可能接近0或1000(任何其他值显示触发器的定时"离场".)第二个值是代码被触发的次数,第三个值是多少次本应该被触发.你会注意到,如果你占用了你的CPU它可以完全离开现场,但它似乎纠正自己.尝试运行它更长一段时间,看看它是如何处理的.

  • 这是上面的实时版本,略微调整以显示浏览器中的输出并更清楚:http://jsfiddle.net/hqmLg/1/ (7认同)
  • [`driftless`](https://github.com/dbkaplun/driftless)是`setInterval`的替代品,可以缓解漂移. (2认同)