【问题标题】:setTimeout function and asynchronous functionsetTimeout 函数和异步函数
【发布时间】:2013-09-25 12:29:51
【问题描述】:

这是关于 setTimeout 如何执行其回调的。

我有以下

function f1 (argument) {
    console.log('f1 start');
    for(var i = 0; i < 100000; ++i)
        for(var j = 0; j < 10000; ++j);
    console.log('f1 complete');
}

function f2 (argument) {
    console.log('f2 start');
    for(var i = 0; i < 1000; ++i)
        for(var j = 0; j < 10000; ++j);
    console.log('f2 complete');
}

function f3 (argument) {
    console.log('f3 start');
    for(var i = 0; i < 10000; ++i)
        for(var j = 0; j < 10000; ++j);
    console.log('f3 complete');
}

setTimeout(f1,0);
setTimeout(f2,0);
setTimeout(f3,0);
console.log('In main2');

输出:

在main2中

f1 开始

f1 完成

f3 开始

f3 完成

f2 开始

f2 完成

John Resig 在他的articlesetTimeout 中解释说,将所有回调排队,直到当前代码块完成执行。这个 StackOverflow answer 解释了即使看起来好像事件是立即触发的,但它们实际上是排队的。

您会注意到,在上面的代码中,f1() 是最长的,其次是 f3(),然后是 f2()

我的问题是,为什么观察到的顺序(首先是f1,然后是f3,最后是f2)?如果事件被排队,它应该与它们被调用的顺序相同(f1,f2,f3)。 JavaScript 引擎如何以及为什么首先选择最长的作业?

[编辑] 注意:以上代码是在 Node.js 中运行的

【问题讨论】:

  • 看看这个:github.com/caolan/async
  • 我在节点中也得到了排序输出f1 f2 then f3
  • 我不明白您如何获得该输出。必须始终按顺序调用函数(即f1,然后是f2,然后是f3)。 JavaScript 没有办法在不分析它的情况下找出最长的函数。异步函数总是排队。

标签: javascript node.js asynchronous scheduled-tasks settimeout


【解决方案1】:

我已经在 firebug 控制台中尝试了您的代码,并且我按照以下顺序得到了输出,我认为这符合预期。

在 main2 f1 开始 f1 完成 f2 开始 f2 完成 f3 开始 f3 完成

我正在使用 Firefox 12.0 和 Fedora。

【讨论】:

    【解决方案2】:

    不管“javascript引擎”问题(没有这样的东西,有language specification和不同的实现),因为它取决于(见another answer),如果你想确保你可能想要使用承诺一个特定的顺序。

    https://github.com/kriskowal/q查看Q库

    或者这个 RSVP 库https://github.com/tildeio/rsvp.js

    Promises/a+ 规范是 here

    可用于节点和浏览器

    我自己在节点 v0.10.21 上的测试(与 firefox 和 chromium 的控制台相同):

    ~/workspace/tmp$ node test.js 
    In main2
    f1 start
    f1 complete
    f2 start
    f2 complete
    f3 start
    f3 complete
    

    【讨论】:

    • 感谢这个 SO 问题 - 让我想知道 John Resig 文章的来源。仅供参考,Javascript Engine 上有一个 wiki 页面。所以,说有这样的事情也不是完全错误的吧? :)
    • 该 wiki 文章中有一个“实现”部分说明了我所说的,但是是的,这样说也不是完全错误的 :)
    猜你喜欢
    • 2020-06-29
    • 2021-06-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多