我在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]。 –