繁体   English   中英

是否在Javascript中按顺序执行相同的超时?

[英]Are equal timeouts executed in order in Javascript?

假设我这样做

setTimeout(foo, 0);

...

setTimeout(bar, 0);

我可以确定foo会在开始执行之前吗? 如果不是0,我会使用1,10或100的超时来表示条形码?

简单的实验表明,在超时值相等的情况下,超时目标的执行顺序与setTimeouts本身相同,但依赖此行为是否安全?

依赖这种行为是不安全的。 我编写了一个测试脚本,它使用setTimeout(...,0)来调度许多函数(并且它们又调度了许多函数),并且调用函数的顺序并不总是与调用setTimeout的顺序 (至少在我用来运行脚本的Chrome 11中)。

您可以在此处查看/运行脚本: http//jsfiddle.net/se9Jn/ (该脚本使用YUI进行跨浏览器兼容,但Y.later在内部使用setTimeout)。

请注意,如果您只是运行脚本并盯着控制台,则可能看不到违规排序。 但是如果启动脚本,切换到另一个选项卡,加载一些页面,然后返回测试页面,您应该会在控制台中看到有关回调的错误。

如果您需要保证订购,我建议在上一个函数结束时安排下一个函数:

setTimeout(foo, 0);

...

function foo() {

    ...

    setTimeout(bar, 0);
}

我通读了Firefox源代码,至少对于那个浏览器,有一个顺序保证超时,以非递减顺序指定。 否则所有投注都会被取消。

具体来说,如果在给定的执行上下文中为n设置了超时,然后为m设置了一个超时,其中n <= m,则将按设置超时的顺序执行目标。

但是不要相信我的话。 我相信窗口实现在nsGlobalWindow.cpp中,实际决定超时在执行队列中的位置的方法称为InsertTimeoutIntoList 看起来该方法向后遍历队列,查找小于或等于给定超时的第一个超时,并在其后插入给定的超时。

当然,当设置超时时,当前时钟时间被添加到超时值。 这就是为什么超时值必须按非递减顺序才能按顺序执行目标。

总之,不要指望它。 看看这个

这个图中有很多信息要消化,但完全理解它可以让你更好地实现异步JavaScript执行的工作方式。

答案是:不,执行顺序无法保证。 我偶尔会看到chrome 40中的非FIFO排序,特别是如果我在超时待机时暂停调试器。 我在野外也有一次罕见的瞄准 - 这是我调查过的事件的唯一合理解释。

如果您需要保证执行顺序,而不是setTimeout(callback, 0)您可以这样做:

var queue = [];
function handleQueue() {
    queue.shift()();
}
function queueCallback(callback) {
   queue.push(callback);
   setTimeout(handleQueue, 0);
}

现在,为了保证foobar你可以:

queueCallback(foo);
...
queueCallback(bar);

延迟实际上有一定的最小值,这在很大程度上取决于操作系统,浏览器,浏览器活动和计算机负载。 我倾向于不会低于20毫秒,因为我认为任何不足之处都没有任何区别。

当你把两个相等的延迟放在一起时,并不一定意味着它会按顺序发生。

如果你想确保它按顺序完成我倾向于做这样的事情:

setTimeout(function() { 
  foo();
  setTimeout(bar, 20)
}, 20);

这将始终保证订单。

如果您使用的是Firefox,为了确保您的javascript实际上是多线程的,您可能需要查看较新的浏览器支持的WebWorker,而不是IE。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM