我正在浏览html5boilerplate github,然后去看了一些面试问题,我遇到了这个问题,我不明白为什么它按顺序输出。我以为不是它的输出是一四二三。有人可以解释为什么吗?太简单了,抱歉。
问题:以下代码显示什么?
console.log('one');
setTimeout(function() {
console.log('two');
}, 0);
Promise.resolve().then(function() {
console.log('three');
})
console.log('four');
输出顺序为“一个”,“四个”,“三个”,最后是“两个”
答案 0 :(得分:5)
这是由于JS调用堆栈所致; setTimeout
和Promise.resolve().then
都是异步调用。
setTimeout(function(){...}, 0)
仅将当前调用堆栈完成执行后的代码排队等待运行,与Promise.resolve().then()
完全相同(尽管有一个子队列)。子队列完成执行,因此为什么three
出现在two
之前,然后主队列完成了,所以现在可以调用setTimeout
。
答案 1 :(得分:5)
我认为输出one
和four
很清楚。 setTimeout
是主要任务队列的一部分,而Promise
是微任务队列的一部分,这就是“三个”,最后是“两个”的原因已打印。
分步执行如下:
执行脚本时,首先执行 console.log(“一个”)。
遇到setTimeout(…)
时,运行时将在0ms之后启动一个计时器。 function() {}
中的回调setTimeout(…)
在任务队列中排队。
遇到promise对象时,其回调(即function() {}
)将排队在微型任务队列中。
最后,它执行最后一个console.log(“four”)
。
根据标准规范
一旦调用栈被清空,它将检查Micro任务队列并找到promise的回调function() {}
。调用栈将执行它(记录三)。
再次,在处理Micro任务队列中的回调后,将清空调用堆栈。最后,事件循环从“任务”队列中选取了一个新任务,即function() {}
的回调setTimeout(…)
(记录两个)执行该任务。
视觉图像