【发布时间】:2010-11-02 09:48:45
【问题描述】:
这确实是一个非常简单的问题。如果我使用setInterval(something, 1000),我是否可以完全确定在 31 天之后它会准确地触发“某事”60*60*24*31 次?或者所谓的漂移有风险吗?
【问题讨论】:
这确实是一个非常简单的问题。如果我使用setInterval(something, 1000),我是否可以完全确定在 31 天之后它会准确地触发“某事”60*60*24*31 次?或者所谓的漂移有风险吗?
【问题讨论】:
简短回答:不,你不能确定。是的,它可以漂移。
长答案:Accuracy of JavaScript Time 和 How JavaScript Timers Work 上的 John Resig。
来自第二篇:
为了了解计时器在内部的工作方式,需要探索一个重要的概念:计时器延迟无法保证。由于浏览器中的所有 JavaScript 都在单个线程上执行,因此异步事件(例如鼠标点击和计时器)仅在执行有空位时运行。
这两篇文章(以及该网站上的任何内容)都非常适合阅读,因此请阅读。
【讨论】:
这是您可以在 Firefox 中运行的基准测试:
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(任何其他值都显示触发的时间有多“离场”。)第二个值是代码被触发的次数,第三个值是应该被触发了多少次。你会注意到,如果你占用你的 CPU,它可能会离场,但它似乎会自行纠正。尝试运行更长的时间,看看它是如何处理的。
【讨论】:
driftless 是 setInterval 的替代品,可减轻漂移。
(对不起我的英语不好) 我在倒计时函数方面遇到了同样的问题,我编写了一个函数 countdown() 并使用 setInterval 循环,但它每个循环漂移 1-3 毫秒。然后我写了一个函数来控制是否有任何漂移并修复它。
它只控制真正的分钟和秒。这里是。它对我来说很好,我希望它也能帮助你。
$.syncInterval(functionname,interval,controlinterval)
示例:
countdown(){ some code };
$.syncInterval(countdown,1000,60);
它说每 1000 毫秒运行一次倒计时功能并每 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);
};
【讨论】: