超时和承诺功能的执行顺序(主要任务和微型任务)

时间:2018-08-07 14:06:32

标签: javascript

我正在浏览html5boilerplate github,然后去看了一些面试问题,我遇到了这个问题,我不明白为什么它按顺序输出。我以为不是它的输出是一四二三。有人可以解释为什么吗?太简单了,抱歉。

问题:以下代码显示什么?

console.log('one');
setTimeout(function() {
  console.log('two');
}, 0);
Promise.resolve().then(function() {
  console.log('three');
})
console.log('four');

输出顺序为“一个”,“四个”,“三个”,最后是“两个”

2 个答案:

答案 0 :(得分:5)

这是由于JS调用堆栈所致; setTimeoutPromise.resolve().then都是异步调用。

setTimeout(function(){...}, 0)仅将当前调用堆栈完成执行后的代码排队等待运行,与Promise.resolve().then()完全相同(尽管有一个子队列)。子队列完成执行,因此为什么three出现在two之前,然后主队列完成了,所以现在可以调用setTimeout

答案 1 :(得分:5)

我认为输出onefour很清楚。 setTimeout主要任务队列的一部分,而Promise微任务队列的一部分,这就是“三个”,最后是“两个”的原因已打印。

分步执行如下:

  1. 执行脚本时,首先执行 console.log(“一个”)

  2. 遇到setTimeout(…)时,运行时将在0ms之后启动一个计时器。 function() {}中的回调setTimeout(…)在任务队列中排队。

  3. 遇到promise对象时,其回调(即function() {})将排队在微型任务队列中。

  4. 最后,它执行最后一个console.log(“four”)

根据标准规范

  1. 一旦调用栈被清空,它将检查Micro任务队列并找到promise的回调function() {}。调用栈将执行它(记录三)

  2. 再次,在处理Micro任务队列中的回调后,将清空调用堆栈。最后,事件循环从“任务”队列中选取了一个新任务,即function() {}的回调setTimeout(…) (记录两个)执行该任务。


视觉图像

Visual Image