javascript中async, await的输出顺序

在快手面试的时候,遇到了让我判断输出顺序的问题。但是async和await机制我一直搞不太懂,上网查阅了很多资料,依然一知半解。求各位指导。
async function bar() {
  console.log(4)
  setTimeout(() => console.log(5), 500)
}

async function foo() {
  console.log(1)
  await bar() // 1 4 3 2 5
  // bar() // 1 4 2 3 5
  console.log(2)
}

foo()
console.log(3)
当给bar()加上await时,程序的输出是1 4 3 2 5,不加await时输出是1 4 2 3 5,不加await我能理解,但是加了await之后的输出我就想不明白了。
执行foo()的时候,先输出1,然后执行bar(),bar整个函数体被放入一个Promise,然后输出4,接下来就不懂为什么会输出3。
求指导。感激不尽。

为了帮助题主理解,我把属于同一个调用时机的放一起讲解,以下讲解只针对加await的情况
1、同步代码
第一步先执行同步代码。代码中,1/4/3 属于同步代码。这里为什么4被当做同步代码,后面会提到。其次你提到一点,"bar整个函数体被放入一个Promise" 其实理解还有点偏差,应该是把 await 之后的所有代码,放入一个Promise中,也就是包括 bar()console.log(2)

2、微任务(也就是题中的 Promise 部分)
上一步,被await修饰的代码,都被放入一个Promise中。同步代码执行完毕后,开始执行Promise,从题中看,只有 2 是属于Promise之后的内容

3、宏任务(也就是题中的 setTimeout)
Promise执行完毕后,轮到 setTimeout 执行,因此输出了5。

注:至于上方提到的为何4 是属于同步代码,你可以看下如下示例,其中 1/2 都是同步代码,而只有 3 才是 Promise 的异步回调

console.log(1)
new Promise((resolve, reject) => {
  console.log(2)
}).then(() => console.log(3))

我懂了,推荐看这篇文章
https://knightyun.github.io/2019/08/02/js-async-await

您好,我是有问必答小助手,您的问题已经有小伙伴帮您解答,感谢您对有问必答的支持与关注!
PS:问答VIP年卡 【限时加赠:IT技术图书免费领】,了解详情>>> https://vip.csdn.net/askvip?utm_source=1146287632