async(await)知识点

  • async 函数是 Generator 函数的语法糖。

  • async 函数对 Generator 函数的改进体现在:

  1. async 内置执行器。
    Generator 函数的执行必须靠执行器,需要调用 next() 方法,或者用co 模块;
    而 async 函数自带执行器。也就是说,async 函数的执行与普通函数一模一样,只要一行。
  2. 更好的语义。
    async 和 await 比起星号和 yield,语义更清楚。
  3. 更广的适用性。
    co 模块约定,yield 命令后面只能是 Thunk 函数或 Promise 对象,
    而 async 函数的 await 命令后面可以是 Promise 对象和原始类型的值(数值、字符串和布尔值,但这时等同于同步操作)。
  4. async 返回值是 Promise,可以用 then 方法指定下一步的操作。
    比 Generator 函数的返回值是 Iterator 对象方便多了。
  • async函数返回的 Promise 对象的状态变化
    async函数返回的 Promise 对象,必须等到内部所有await命令后面的 Promise 对象执行完,才会发生状态改变,除非遇到return语句或者抛出错误。也就是说,只有async函数内部的异步操作执行完,才会执行then方法指定的回调函数。

  • await 命令
    正常情况下,await命令后面是一个 Promise 对象。如果不是,会被转成一个立即resolve的 Promise 对象。

  • 只要一个await语句后面的 Promise 变为reject,那么整个async函数都会中断执行。
    有时,我们希望即使前一个异步操作失败,也不要中断后面的异步操作。这时可以将第一个await放在try...catch结构里面,这样不管这个异步操作是否成功,第二个await都会执行。

async function f() {
  try {
    await Promise.reject('出错了');
  } catch(e) {
  }
  return await Promise.resolve('hello world');
}
f()
.then(v => console.log(v))
// hello world

另一种方法是await后面的 Promise 对象再跟一个catch方法,处理前面可能出现的错误。

async function f() {
  await Promise.reject('出错了')
    .catch(e => console.log(e));
  return await Promise.resolve('hello world');
}
f()
.then(v => console.log(v))
// 出错了
// hello world
  • 使用注意点:
  1. await命令后面的Promise对象,运行结果可能是rejected,所以最好把await命令放在try...catch代码块中。
// 第1种写法
async function myFunction() {
  try {
    await somethingThatReturnsAPromise();
  } catch (err) {
    console.log(err);
  }
}
// 第2种写法
async function myFunction() {
  await somethingThatReturnsAPromise()
  .catch(function (err) {
    console.log(err);
  });
}
  1. 多个await命令后面的异步操作,如果不存在继发关系,最好让它们同时触发。
    不同时触发(继发)的语句:
let foo = await getFoo();
let bar = await getBar();

上面代码中,getFoo和getBar是两个独立的异步操作(即互不依赖),被写成继发关系。这样比较耗时,因为只有getFoo完成以后,才会执行getBar,完全可以让它们同时触发。
同时触发的语句:

// 写法一
let [foo, bar] = await Promise.all([getFoo(), getBar()]);
// 写法二
let fooPromise = getFoo();
let barPromise = getBar();
let foo = await fooPromise;
let bar = await barPromise;

上面两种写法,getFoo和getBar都是同时触发,这样就会缩短程序的执行时间。
3. await命令只能用在async函数之中,如果用在普通函数,就会报错。

原文地址:https://www.cnblogs.com/cag2050/p/7542978.html