深入浅出 async

基本概念

简单来讲,async 就是 Generator 函数的语法糖

表面上一比较,就可以发现 async 就是将 Generator 函数的型号(*)替换成 async,将 yield 替换成 await,本质则是,async 内置执行器返回值是 Promise

改进体现在以下四点:

内置执行器

Generator 需要调用 next 或者 co 模块才可以真正的执行,而 async 只需像普通函数一样调用即可

更好的语义

asyncawait,比起星号和 yield,语义更清楚。async 代表函数里有异步操作,await 表示紧跟在后面的表达式需要等待结果

更广的适用性

co 模块约定,yield 后面只能是 Thunk 函数或 Promise 对象,而 async 函数的 await 命令后面,可以是 Promise 对象和原始类型的值(数值、字符串和布尔值,但这是会自动转成立即 resolvedPromise 对象)

返回值是 Promise

async 函数的返回值是 Promise 对象,这比 Generator 函数的返回值是 Iterator 对象方便多了。你可以用 then 方法指定下一步的操作

基本用法

async 函数返回一个 Promise 对象,可以使用 then 方法添加回调函数。当函数执行的时候,一旦遇到 await 就会先返回,等到异步操作完成,才会再接着执行函数体内后面的语句

栗子

function timeout(ms) {
  return new Promise((resolve) => {
    setTimeout(resolve, ms)
  })
}

async function asyncPrint(value, ms) {
  await timeout(ms)
  console.log(value)
}

asyncPrint('hello world', 5000)

上面代码指定 5 秒之后,输出 hello world

错误处理

await 后面的异步操作出现错误,则等同于 async 函数返回的 Promise 对象被reject

async function f() {
  await new Promise(function (resolve, reject) {
    throw new Error('出错了')
  })
}

f()
.then(v => console.log(v))
.catch(e => console.log(e))
// Error: 出错了

Last updated