async/await 改成Promise等价写法

5 阅读1分钟

这道题如果 完全用 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% 前端第一眼都会算错。