为什么在setTimeout之前解决了Promise

时间:2020-07-05 19:34:42

标签: javascript node.js promise settimeout

我有以下说明

console.log(1)
setTimeout(() => {
  console.log(3)
});
Promise.resolve().then(() => console.log(4))
console.log(7)

输出为:

1
7
4
3

执行顺序如下:

  • 执行控制台
  • 承诺已解决
  • settimeout已执行

为什么在setTimeout之前解决了Promise?两者都由回调处理,对吧?

2 个答案:

答案 0 :(得分:2)

有趣的问题。为了理解原因,需要了解JavaScript事件循环。

.then()将微任务排队。 JS调用堆栈清空后,便会立即执行微任务。

在这种情况下(but not in all cases),setTimeout在主任务队列中将任务排队。任务被排队等待外部事件,计时器处理程序,渲染(在浏览器中)等。如果一个任务调用JS代码,则下一个任务将在与它相关联的所有微任务完成运行后才会运行。

这就是正在发生的事情

  1. 任务1,由Node.js在内部排队:
    1. console.log(1)日志1输出为1
    2. setTimeout(() => { console.log(3) });任务排队以记录3
    3. Promise.resolve().then(() => console.log(4))排队 microtask 记录4
    4. console.log(7)日志7输出为1 7
    5. 由于没有更多的语句,JS堆栈为空。微任务开始执行。
      1. 微任务#1-1,由.then()排队:
        1. 记录4输出为1 7 4
  2. 任务2,由setTimeout()排队:
    1. 记录3输出为1 7 4 3
    2. 由于没有更多的语句,所以JS堆栈为空,但是没有微任务。 最终输出:
1
7
4
3

答案 1 :(得分:1)

在代码块完成后,将立即调用Promise .then()回调。计时器将获得约15或16毫秒的默认最小时间,因此肯定会在此之后发生。

edit -显然,在这个疯狂的现代世界中,最小时间约为4毫秒,而不是15或16。

相关问题