我在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'在控制檯出現三次),然後停止。
無法重現,請加演示該問題的完整樣本分配ID,以防止這種情況今後發生。 –
也許正在修改'setTimeout'方法。我的意思是這樣的'window.setTimeout = function(){}' – Curious
@Zub我確實考慮過這一點。我做了'console.log(setTimeout)'並且它沒有改變[native code]。 –