请问setInterval漂移?

这真的是一个非常简单的问题。 如果我使用setInterval(something, 1000) ,我可以完全确定,在31天后,它会触发“东西”正好60*60*24*31次? 还是有所谓漂stream的风险?

以下是您可以在Firefox中运行的基准testing:

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

第一个值应尽可能接近于0或1000(其他任何值都表示触发时间是“非现场”)。第二个值是代码被触发的次数,第三个值是多less次应该已经触发了。 你会注意到,如果你停止CPU,它可能会变得不合时宜,但它似乎是自行改正的。 尝试运行一段时间,看看它是如何处理的。

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

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

从第二篇文章:

为了了解定时器如何在内部工作,有一个重要的概念需要探索:定时器的延迟是不能保证的。 由于浏览器中的所有JavaScript脚本都是在单线程上执行的,因此只有在执行过程中有一个开始时才会运行asynchronous事件(如鼠标点击和计时器)。

这两篇文章(以及该网站上的任何内容)都是非常棒的阅读材料。

(对不起我的英语不好)我有倒计时function相同的问题,我写了一个函数countdown()和循环与setInterval但它的漂移每个循环1-3毫秒。 然后我写一个控制的function是否有任何漂移并修复它。

它只用真实的分钟和秒钟进行控制。 这里是。 它的作品对我很好,我希望它也能帮助你。

 $.syncInterval(functionname,interval,controlinterval) 

例:

 countdown(){ some code }; $.syncInterval(countdown,1000,60); 

它说每1000毫秒运行倒计时function,并每60秒检查一次

这里是代码:

 $.syncInterval = function (func,interval,control) { var now=new Date(); realMinute=now.getMinutes(), realSecond=now.getSeconds(), nowSecond=realSecond, nowMinute=realMinute, minuteError=0, countingVar=1, totalDiff=0; var loopthat = setInterval(function(){ if (nowSecond==0) { nowMinute++; nowMinute=nowMinute%60; }; if (countingVar==0){ now=new Date(); realSecond=now.getSeconds(); realMinute=now.getMinutes(); totalDiff=((realMinute*60)+(realSecond))-((nowMinute*60)+(nowSecond)); if(totalDiff>0){ for (i=1;i<=totalDiff;i++) { func(); nowSecond++; countingVar++; }; } else if (totalDiff==0){ func(); nowSecond++; countingVar++; } else if (totalDiff<0) { }; } else { func(); nowSecond++; countingVar++; }; countingVar=countingVar%control; nowSecond=nowSecond%60; },interval); };