2014-01-11 66 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以下