【问题标题】:JavaScript execution order of setTimeout() callbacks with different delays不同延迟的 setTimeout() 回调的 JavaScript 执行顺序
【发布时间】:2016-01-06 12:33:32
【问题描述】:

如果同时注册了多个回调,是否保证第一个被调用的回调是延迟最少的?

考虑以下代码:

function foo(i) {
    setTimeout(function () {
        console.log(i);
    }, i);
}

for (var i = 0; i < 1000; i++) {
    foo(i);
}

这段代码是否保证按顺序输出1-1000?


请注意:这个问题不是关于使用相等延迟。已经确定,具有相同延迟的多个 setTimeout() 调用保证按顺序执行。

【问题讨论】:

  • 是的,当延迟以这种方式增加时,可以保证回调将按顺序触发,但不能保证计时器准确。
  • 能否请教一下“多个具有相同延迟的 setTimeout() 调用不能保证按顺序执行”?因为这至少看起来与 HTML 规范相冲突。请参阅stackoverflow.com/a/53244931/2160440 虽然不确定服务器端的实现。

标签: javascript settimeout


【解决方案1】:

是的!!

function foo(i) {
    setTimeout(function () {
        console.log(i);
    }, i);
}

for (var i = 1; i <= 1000; i++) {
    foo(i);
}

解释:

当您调用setTimeout 时,无论setTimeout 正在运行或将运行多少,它都会独立执行,因此它取决于您调用的时间和您设置的时间。希望您能明白这一点。

【讨论】:

    【解决方案2】:

    我知道很多人已经回答了这个问题。但是,大多数人并不确切地知道事件循环是如何工作的。即使我最近得到它。所以,我认为这对所有看到这篇文章的人都有帮助。

    setTimeout() 函数根据事件回调和渲染队列工作。渲染队列是无法保证您的回调将在确切超时后执行的原因。有像

    这样的概念
    1. 调用堆栈,
    2. web api 和
    3. 回调队列

    您多次调用以下函数,

    function foo(i) {
        setTimeout(function () {
            console.log(i);
        }, i);
    }

    所以流程是这样的,每次调用foo(i) 都会首先调用堆栈。一旦调用堆栈到达其顶部(当循环结束时),Web api(特定于浏览器)将一一处理从堆栈中弹出的函数,然后在达到超时时移动到回调队列。根据可用性,即如果未进行渲染,则执行回调。

    在回调队列中,函数按调用顺序排列。

    所以,顺序是有保证的。

    下面的文章可以更好地理解事件队列。

    Philip Roberts: What the heck is the event loop?

    【讨论】:

    • "函数按调用顺序排列" 这显然仅适用于使用 setTimeout 注册的回调,但延迟不相等,因为如果使用相等的延迟,则无法保证回调执行顺序。
    • @Richard 如果您使用相等的延迟,则将从堆栈中考虑订单。后进先出
    猜你喜欢
    • 2019-04-14
    • 2015-07-24
    • 1970-01-01
    • 2013-04-25
    • 1970-01-01
    • 1970-01-01
    • 2011-06-19
    • 2016-12-01
    • 1970-01-01
    相关资源
    最近更新 更多