async函数【ES6】

2019-03-28

async函数【ES6】

async函数是Generator和Promise结合的语法糖,具体来说就是将Generator函数的*声明符换为async,将yield换为await。关于Generator函数可以看我的另外一篇文章

这样做会有如下效果:

  1. 内置执行器

    一个async函数会一直执行到结束,输出最终结果,而不像Generator需要自己写执行器。

  2. 返回值是Promise

    async函数的return返回值用Promise对象进行了包装,用Promise的语法来执行下一步操作

  3. 将多个Promise组合成一个串行函数

    await操作符后是一个Promise对象,如果不是,会被转换成一个已经resolve的Promise对象。当遇到一个await表示式时会立即返回,等待await后的Promise内部逻辑结束后继续执行。

语法

function asyncWait() {
  return new Promise((resolve)=>{
    setTimeout(resolve,1000);
  })
}

async function f() {
  await asyncWait();
  await asyncWait();
  return "over"
}

f().then(data=>console.log(data));
  1. 通过async关键字声明async函数
  2. await操作符后跟Promise对象
  3. return的值自动用Promise包装
  4. 像Generator的yield一样,async执行到await表达式会停止执行,但是重新开始状态变化是等到await后的Promise执行完自动开始。

错误处理

async函数的语法导致其错误处理比较复杂,当await后的Promise执行中抛出错误(指调用全局throw),或调用reject,将会用Promise的错误处理机制来处理错误。

async function f(){
  await new Promise((resolve)=>{throw new Error('出错')});
}

//等价写法
async function f(){
  await new Promise((resolve,reject)=>{reject('出错')});
}

try{
  f().then(v=>console.log('继续执行'+v))
    .catch((e=>console.log('发生错误'+e)));
}catch(e){
  console.log('抓不到错误'+e);
}
// 发生错误Error: 出错

和其他异步方法的关系

ES6添加的三个主要的异步方法即:Promise, Generator, Async,个人对这三个方法区别的看法是:

  • Promise: 以对象链式调用的方法处理异步逻辑;
  • Generator: 状态机,本身不是用来专门用于异步逻辑,需要外部执行器处理异步逻辑;
  • async: 以状态机的方式自动处理异步逻辑,不需要外部处理器,内部用到了Promise来实现;