我有以下代码:
function wait(ms) {
var start = +(new Date());
while (new Date() - start < ms);
}
(function() {
setTimeout(function(){console.log(2)}, 1000);
setTimeout(function(){console.log(3)}, 0);
setTimeout(function(){console.log(4)}, 0);
wait(2000); //!!! blocking events processing here
})();
Run Code Online (Sandbox Code Playgroud)
它输出:
3
4
2
Run Code Online (Sandbox Code Playgroud)
我已经阅读setTimeout了一个向事件队列添加函数的地方,然后当这个函数是链中的第一个时,它检查指定的时间是否已经过去,如果没有,它会推迟执行.根据这个逻辑,我期望上面的代码输出:2,3,4因为wait()函数阻塞事件链接处理和调用堆栈完成,浏览器终于有时间处理通过setTimeout添加的函数,所有三个函数都按添加的顺序放入队列中,1000个已经为第一个函数传递,所以浏览器可以接受并执行,但它等待第二个和第三个添加的函数.为什么?我逻辑中的错误在哪里?
回调函数在超时期限后进入队列.所以,
setTimeout(function(){console.log(3)}, 0);
setTimeout(function(){console.log(4)}, 0);
Run Code Online (Sandbox Code Playgroud)
立刻进入,但是
setTimeout(function(){console.log(2)}, 1000);
Run Code Online (Sandbox Code Playgroud)
1秒后进入队列.因此订单3,4,2
来自MDN:
调用setTimeout将在作为第二个参数传递的时间之后向队列添加消息.如果队列中没有其他消息,则立即处理该消息; 但是,如果有消息,则setTimeout消息必须等待处理其他消息.因此,第二个参数表示最短时间而不是保证时间.
(强调我的)