2014-01-11 129 views
0

我在JavaScript中很有经验,但我遇到了一个奇怪的问题,在开发一个Web应用程序,其中脚本不是应该如其行为。奇怪的是(实际上)我在使用离线开发副本或登录后没有遇到此问题。但是,当用户已经登录并刷新页面时,他们会遇到此问题。执行影响已设置超时

这里是受影响的方法(这简直是整个事情):

_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'超时确实运行的原因是创建它的呼叫和下一个呼叫之间有200毫秒的差距。

编辑

这发生在至少Chrome和Firefox。

编辑2

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

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

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

+0

无法重现,请加演示该问题的完整样本分配ID,以防止这种情况今后发生。 –

+0

也许正在修改'setTimeout'方法。我的意思是这样的'window.setTimeout = function(){}' – Curious

+0

@Zub我确实考虑过这一点。我做了'console.log(setTimeout)'并且它没有改变[native code]。 –

回答

0

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

我发现了这个问题,并通过覆盖clearTimeout并找出是谁调用它,何时以及用什么id来追踪代码片段。

我试图通过我改装成setTimeout递减,在0以下