async await

发布时间 2023-07-17 16:55:12作者: 年轻浅识

1、async
被 async 操作符修饰的函数必然返回一个 Promise
当 async 函数返回一个值时,Promise 的 resolve 方法负责传递这个值
当 async 函数抛出异常时,Promise 的 reject 方法会传递这个异常值

async function async2() {
    console.log('async2')
}

等价于

function async2(){
  console.log('async2');
  return Promise.resolve();
}

2、await
例await v
await 后的值 v 会被转换为 Promise
即使 v 是一个已经 fulfilled 的 Promise,还是会新建一个 Promise,并在这个新 Promise 中 resolve(v)
await v 后续的代码的执行类似于传入 then() 中的回调

async function async1() {
    console.log('async1 start')
    await async2()
    console.log('async1 end')
}

低版本规范同等于:

function async1(){
  console.log('async1 start')
  return new Promise(resolve => resolve(async2()))
    .then(() => {
      console.log('async1 end')
    });
}

在 Promise 中 resolve 一个 thenable 对象,需要先将 thenable 转化为 Promsie,然后立即调用 thenable 的 then 方法;
因此

new Promise((resolve) => {
    resolve(thenable)
})

执行顺序等价于:

new Promise((resolve) => {
    Promise.resolve().then(() => {
        thenable.then(resolve)
    })
})

最新规范:await v 在语义上将等价于 Promise.resolve(v),而不再是 new Promise(resolve => resolve(v))
Promise.resolve(v) 不等于 new Promise(r => r(v)),因为如果 v 是一个 Promise 对象,前者会直接返回 v,而后者转换thenable为Promise(PromiseResolveThenableJob),会有两个微任务时序。

function async1(){
    console.log('async1 start');
    return Promise.resolve(async2())
        .then(() => {
            console.log('async1 end')
        });
}