繁体   English   中英

Firefox太快调用setTimeout函数(或Date.getTime()关闭?)

[英]Firefox invokes setTimeout function too soon (or Date.getTime() is off?)

我在Firefox 12中遇到了一个奇怪的问题.setTimeout()似乎并不总是等待适当的长度。 或者也许这是没有jive的日期毫秒?

看看这个小提琴。 从本质上讲,100ms的setTimeout似乎可以在80ms到110ms之间运行。 根据John Resig对计时器的解释,我可以理解更多。 但少?

您可能需要刷新一次或两次以查看问题,因为它有时在第一次运行时正常工作。 它似乎在IE和Chrome中起着很大的作用。

这是我在小提琴中使用的代码:

var txt = '',
    TIMEOUT_LENGTH = 100,
    _now;

now = Date.now || function() { return new Date().getTime() };

function log(time) {
    c = time < 100? 'class="error"' : '';
    $('#log').append('<p '+c+'>waited ' + time + '</p>');
}

function defer() {
    var d = $.Deferred(),
        start = now();
    setTimeout(function() {
        d.resolve(now() - start);
    }, TIMEOUT_LENGTH);
    return d.promise();
}

for (var i = 0; i < 20; i++) {
    defer().then(log);
}

以下是古怪输出的示例:

在此输入图像描述

这是我的浏览器信息:

在此输入图像描述

非常感谢你阅读我的问题! 我希望有人可以对此有所了解。

更多信息

我通过使用setInterval()并检查每个增量以查看是否已经过了所需的时间来解决这个问题。 看到这个小提琴

但是,我仍然非常有兴趣听听是否有人能够解决问题的根源

是。 setTimeout的准确性基于许多因素,并不保证始终在您指定的确切时间执行。

我不能用任何权威来说这个,但是我猜测Firefox试图看起来更快,会暂时加速JS引擎以使一切运转起来(这很有趣,因为根据我的经验,基于计时器函数实际上最初在我的firefox版本中运行较慢)。

setTimeoutsetInterval都没有承诺它们将在恰当的时间执行,就像您发布的链接所述。 但是,使用setInterval ,你可以获得定时器循环的好处,如果它落后太远就可以通过追赶来“纠正自己”,所以无论你想做什么,它都可能更合适。

无论如何,这是我在Macbook 10.6.8上的结果:

Firefox 5.0.1:

waited 92
waited 92
waited 93
waited 93
waited 93
waited 93
waited 93
waited 94
waited 93
waited 93
waited 93
waited 93
waited 94
waited 94
waited 94
waited 94
waited 94
waited 95
waited 96
waited 96

Safari 5.1.5:

waited 100
waited 104
waited 104
waited 103
waited 104
waited 104
waited 104
waited 104
waited 104
waited 104
waited 104
waited 104
waited 104
waited 104
waited 104
waited 104
waited 104
waited 104
waited 104
waited 104

Chrome 19.0.1084.52:

waited 101
waited 103
waited 103
waited 104
waited 104
waited 103
waited 103
waited 103
waited 103
waited 103
waited 103
waited 103
waited 103
waited 103
waited 104
waited 104
waited 104
waited 104
waited 104
waited 104

JavaScript是同步的。 浏览器会将您的setTimeout添加到队列中并在之后执行

  1. 倒计时结束了
  2. 它已完成倒计时结束时队列中的任何其他任务。

我编写了以下函数来确保我的代码至少在给定的毫秒数后执行。 我用它而不是setTimeout

mySetTimeout=function(f,t){
    var endTime=new Date().valueOf()+t;
    setTimeout(function(){
        var now=new Date().valueOf();
        if(now<endTime){
            mySetTimeout(f,endTime-now);
        }else{
            f();
        }
    },t);
};

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM