setTimeout函数和异步函数

时间:2013-09-20 07:37:20

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

这是关于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()是最长的,其次是f 3(),然后是f2()

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

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

2 个答案:

答案 0 :(得分:1)

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

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

我正在使用带有fedora的firefox 12.0。

答案 1 :(得分:1)

无论“javascript引擎”问题(没有这样的东西,都有language specification和不同的实现),因为它依赖于(见another answer),你可能想要使用promises if你想确保一个特定的顺序。

https://github.com/kriskowal/q

检查Q库

或此RSVP库https://github.com/tildeio/rsvp.js

Promises / a + spec是here

可用于节点和浏览器

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

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