Javascript 时间间隔会漂移吗?

Javascript 时间间隔会漂移吗?,javascript,setinterval,Javascript,Setinterval,这是一个非常简单的问题。如果我使用setInterval(something,1000),我是否可以完全确定,比如说,在31天之后,它会触发“something”准确的60*60*24*31次?或者说有所谓漂流的风险吗?简短的回答:没有,你不能确定。是的,它可以漂移 长回答:约翰·雷斯格在和上 第二条: 为了理解定时器如何在内部工作,有一个重要的概念需要探讨:定时器延迟不能保证。由于浏览器中的所有JavaScript都在单线程上执行,因此异步事件(如鼠标单击和计时器)仅在执行过程中出现漏洞时运行

这是一个非常简单的问题。如果我使用
setInterval(something,1000)
,我是否可以完全确定,比如说,在31天之后,它会触发“something”准确的
60*60*24*31次?或者说有所谓漂流的风险吗?

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

长回答:约翰·雷斯格在和上

第二条:

为了理解定时器如何在内部工作,有一个重要的概念需要探讨:定时器延迟不能保证。由于浏览器中的所有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,它可能会变得非常不正常,但它似乎可以自我纠正。试着运行更长的时间,看看它如何处理。

(很抱歉我的英语不好) 关于倒计时函数,我也有同样的问题,我编写了一个函数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);
};
$.syncInterval=函数(func,interval,control){
变量
现在=新日期();
realMinute=now.getMinutes(),
realSecond=now.getSeconds(),
nowSecond=realSecond,
nowMinute=realMinute,
分钟错误=0,
countingVar=1,
totalDiff=0;
var loopthat=setInterval(函数(){
if(nowSecond==0){
nowMinute++;
nowMinute=nowMinute%60;
};
if(countingVar==0){
现在=新日期();
realSecond=now.getSeconds();
realMinute=now.getMinutes();
totalDiff=((realMinute*60)+(realSecond))-((nowMinute*60)+(nowSecond));
如果(总差异>0){

对于(i=1;我这里有一个以上的实时版本,稍微调整一下以在浏览器中显示输出,并且更清晰:它从来不会为我校正自己。如果我每秒执行100次,它会达到85次,但如果我输入控制台日志,它会达到30次w/o的速度。-(使用Phrogz演示)嗯,我上面做的测试是在一台大约有10年历史的32位笔记本电脑上的Ubuntu FF上进行的。我在一台新的64位Windows机器上进行了测试,FF更接近。IE和Chrome的平均值在十分之二以内。是不是一种能减少漂移的
setInterval
替代品。我不明白。在第二篇文章中,John Resig说“…setInterval将尝试每10毫秒执行一次回调,而不管最后一次回调是在什么时候执行的。”这意味着setInterval不会漂移。它将尝试,但如果10毫秒后执行被另一个长时间运行的函数阻止,它将漂移。另一个(愚蠢)示例:如果您每10毫秒执行一次的函数需要11毫秒才能运行,该怎么办?第二个函数何时运行?我相信20毫秒后(10毫秒开始将跳过)基本上,一种更简单的方式是用户事件(单击鼠标)当计时器应该结束时可能发生,这可能会中断结束事件。当计时器应该停止时,它可能会占用CPU上的进程。@chowey虽然Resig的声明对于某些实现(例如Chrome、Opera)可能是正确的,但在其他实现(例如Safari、Firefox)中显然是错误的。