跳至主要內容

20. async

Harry Xiong大约 2 分钟Web 前端JavaScriptPromise 对象JS 异步async 与 await

async

为了使得异步操作更加的简便,ES8标准引入了async函数,async函数是Generator函数的语法糖,基本是模仿Generator函数并作出了一些改变

20.1 async与Generator的区别

  • 有了内置执行器,Generator函数的执行必须靠执行器,而async函数自带执行器。也就是说,async函数的执行,与普通函数一样,只要一行就能执行所以过程

  • async的语义比Generator的语义更加的清楚,**命名与使用async函数需要用到asyuc和await关键字,**相对于Generator函数的*和yield更加让人理解,async表示函数内部有异步操作,而await表示在await后面的表达式需要等待结果

  • yeild后面可以是任何数据类型,而正常情况下,await后面是一个Promise对象,如果并没有手动设置一个Promise对象,而后面的表达式会被转成一个立即成功(await后面上面都不写也会传undefined)的Promise对象

  • async后的所有能返回值的结果都是Promise

所以,async函数完全可以看作多个异步操作,包装成的一个 Promise 对象,而await就是内部then()方法的语法糖

20.2 async与Generator函数的应用对比

  • Generator
var fn = function (time) {
  console.log("开始处理异步");
  setTimeout(function () {
    console.log(time);
    console.log("异步处理完成");
    iter.next();
  }, time);

};

function* g(){
  console.log("start");
  yield fn(3000)
  yield fn(500)
  yield fn(1000)
  console.log("end");
}

let iter = g();
iter.next();
  • async
var fn = function (time) {
  return new Promise(function (resolve, reject) {
    console.log("开始处理异步");
    setTimeout(function () {
      resolve();
      console.log(time);
      console.log("异步处理完成");
    }, time);
  })
};

var start = async function () {
  // 在这里使用起来就像同步代码那样直观
  console.log('start');
  await fn(3000);
  await fn(500);
  await fn(1000);
  console.log('end');
};

start();

注意:

如果await后面的异步操作出错,那么等同于async函数返回的Promise对象直接失败,并且会将错误对象作为参数传递给then()方法的第二个函数或者catch()方法回调函数中

async function f() {
  await new Promise(function (success, rejected) {
    throw new Error('error');
  });
}

f().then(function(value){
    console.log(value)
}).catch(function(err){
    console.log(err)//Error:error
});
//用try...catch来捕捉
  async function f() {
      try {
          await new Promise(function(success, rejected) {
              throw new Error("error");
          });
      } catch (err) {
          console.log(err);
      }
      return await "hello world";
  }
f().then(function(data) {
    console.log(data);
});
//如果有多个await命令,可以统一放在try...catch结构中。
async function main() {
  try {
    var val1 = await firstStep();
    var val2 = await secondStep(val1);
    var val3 = await thirdStep(val1, val2);

    console.log('Final: ', val3);
  }
  catch (err) {
    console.error(err);
  }
}