setTimeout调用的集合,间隔为0,1,2,3。
function f() {
setTimeout(function a() {console.log(10);}, 3);
setTimeout(function b() {console.log(20);}, 2);
setTimeout(function c() {console.log(30);}, 1);
setTimeout(function d() {console.log(40);}, 0);
}
f();

输出:(来自chrome。希望在其他浏览器中也是一样)
30
40
20
10
有人可以清楚地解释为什么订购不是30,40,10,20? 据说浏览器保持最小10毫秒或(规格说)4毫秒间隔。如果是这样,请使用时间度量标准或以便于解释此行为的方式验证输出。我错过了什么细节才能理解这种语言的这个特色?
编辑:
我知道这些函数是异步的。我读过John Resig'博客几次。我知道一个setTimeout'回调不保证以指定的间隔执行。
更准确地说,我希望有一个解释可以解释执行队列,事件循环,调用堆栈和计时器方面的行为。
答案 0 :(得分:1)
为了理解定时器如何在内部工作,有一个 需要探索的重要概念:定时器延迟不是 保证。由于浏览器中的所有JavaScript都在单个上执行 线程异步事件(例如鼠标点击和计时器)只是 在执行中有一个开放时运行。
答案 1 :(得分:1)
正如@Jebin在对OP的评论中指出的那样,你在这里遇到了竞争条件。
以下是规范https://html.spec.whatwg.org/multipage/webappapis.html#dom-windowtimers-settimeout
步骤13是我们等待的地方,当脚本当前正在执行时,等待可能会发生。请参阅http://jsbin.com/faguli/edit?js,console - 在此示例中" 10"首先记录,因为脚本需要很长时间才能到达下一个setTimeout
。
据猜测,在Chrome中,第三个setTimeout
的任务在JS管理对setTimeout
的第四次调用之前排队。
因此,在这种情况下,Chrome和Firefox都符合规范,尽管给出了不同的答案。
实现此确定性的一种方法是将setTimeout
调用作为微任务的一部分进行处理,并从那里启动计时器,但setTimeout
是一个olllllld API,因此这里的更改可能会破坏Web