setTimeout函数和asynchronous函数

这是关于如何setTimeout执行其callback。

我有以下几点

 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在他的文章中解释说, setTimeout队列中的所有callback,直到当前的代码块完成执行。 这个StackOverflow 答案解释,即使它看起来好像事件立即被触发,他们实际上排队。

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

我的问题是,为什么观察到的顺序(先f1 ,后f3 ,最后f2 )? 如果事件是排队的,它应该简单地按照它们被调用的顺序( f1f2f3 )。 JavaScript引擎如何以及为什么select最长的工作?

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

不pipe“javascript引擎”的问题(没有这样的事情,有一个语言规范和不同的实现),因为它依赖于(看另一个答案 ),如果你想确保一个特定的序列顺序,你可能想使用promise。

https://github.com/kriskowal/q查看Q&#x5E93;

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

Promises / a +规范在这里

可用于节点和浏览器

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

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

我试过你的代码在萤火虫控制台,我得到了以下顺序的输出,我认为如预期。

在main2中f1启动f1完成f2启动f2完成f3启动f3完成

我使用的是Fedora 12.0的firefox。