这道题如果 完全用 Promise 写出来,本质就是把 await 改成 then。
因为:
await promise
等价于:
promise.then(...)
一、原来的 async / await 代码
console.log(1)
async function async1() {
await async2()
console.log(2)
await async3()
console.log(3)
}
async function async2() {
console.log(4)
}
async function async3() {
console.log(5)
}
async1()
console.log(6)
二、等价的 Promise 写法
console.log(1)
function async2() {
console.log(4)
return Promise.resolve()
}
function async3() {
console.log(5)
return Promise.resolve()
}
function async1() {
return async2().then(() => {
console.log(2)
return async3()
}).then(() => {
console.log(3)
})
}
async1()
console.log(6)
三、执行顺序仍然是
1
4
6
2
5
3
四、关键转换规则(面试重点)
规则1
async function fn() {}
等价于
function fn() {
return Promise.resolve(...)
}
规则2
await promise
等价于
promise.then(...)
规则3
async function a(){
await b()
console.log(1)
}
等价于
function a(){
return Promise.resolve(b()).then(()=>{
console.log(1)
})
}
五、把这题 完整展开后的真实样子
JS 引擎实际更接近下面这样:
console.log(1)
function async2() {
console.log(4)
return Promise.resolve()
}
function async3() {
console.log(5)
return Promise.resolve()
}
function async1() {
return Promise.resolve()
.then(() => async2())
.then(() => {
console.log(2)
return async3()
})
.then(() => {
console.log(3)
})
}
async1()
console.log(6)
六、一个很多人不知道的底层事实
await 会多产生一个微任务。
所以很多执行顺序题里:
await
有时候会比 Promise.then 慢一个微任务。
这也是为什么很多面试题会专门考:
await + then + setTimeout
混合执行顺序。
如果你愿意,我可以给你 一题比这个难 3 倍的执行顺序题(阿里 + 字节前端面试常考版) ,90% 前端第一眼都会算错。