执行影响已设置的超时

时间:2014-01-11 17:00:27

标签: javascript timeout settimeout

我在Javascript方面经验丰富但我在开发一个网络应用程序时遇到了一个奇怪的问题,其中脚本的行为并不像应该的那样。奇怪的是(莫名其妙地,事实上)当我使用我的离线开发副本或登录后,我没有遇到这个问题。但是,当用户已经登录并刷新页面时,他们遇到了这个问题。

这是受影响的方法(这实际上就是整个事情):

_setLiveSyncTimeout: function (firstTestCall) {
    if (firstTestCall) {
        console.log('set next')
        window.setTimeout(function () {
            console.log(200, 'a');
            window.setTimeout(function () {
                console.log(400, 'b');
            }, 200);
        }, 200);

        window.setTimeout(function () {
            console.log(400, 'c');
        }, 400);
    }

    this._liveSyncTimeout = setTimeout(_(this.liveSyncNow).bind(this), this._liveSyncPeriod);
}

我注意到this.liveSyncNow似乎每次都没有被调用,所以我在上面的if语句中添加了调试。奇怪的是,当你传入true时,第一个超时('a')将会运行,但是'b'和'c'不会。由于setTimeout的结果没有存储在这些情况下,因此根本不可能取消它们,但是,由于没有明显的原因,它们根本就不会运行。在“b”和“c”未运行的情况下,this.liveSyncNow的超时也不会运行。

从测试开始,当此函数运行时,之前在其中创建的所有超时都将被取消。 “a”超时运行的原因是,在创建它的呼叫与下一个呼叫之间存在200ms的差距。

修改

这至少发生在Chrome和Firefox中。

修改2

这是一个更简单的问题示例。这是Backbone模型定义的一部分(尽管你不需要担心)。这实际上就是整个功能。

initialize: function () {
    var a = setInterval(function () {
        console.log('test')
    }, 50);
}

setInterval运行三次('test'在控制台中出现三次)然后停止。

1 个答案:

答案 0 :(得分:0)

我遇到了这个问题(不足为奇),因为一段完全不相关的代码错误地取消了我的超时。发生这种情况是因为我使用的是setTimeout的修改版本,它返回了自己的增量分配整数,但我没有使用clearTimeout的正确修改版本,而是使用原始window.clearTimeout。结果我的好时间被错误地取消了。

我发现了这个问题,并通过覆盖clearTimeout并找出谁调用它,何时以及使用什么ID来追踪这些狡猾的代码。

我试图通过在我的修改后的setTimeout递减,低于0来指定ID来防止这种情况发生。