美文网首页
async语法

async语法

作者: 幸宇 | 来源:发表于2020-03-25 21:30 被阅读0次

    async函数的语法规则总体上比较简单,难点是错误处理机制。
    (1)async函数返回一个Promise对象。
    async函数内部return语句返回的值,会成为then方法回调函数的参数。

    async function f() {
      return 'hello world';
    }
    
    f().then(v => console.log(v))
    // "hello world"
    

    上面代码中,函数f内部return命令返回的值,会被then方法回调函数接收到。

    async函数内部抛出错误,会导致返回的Promise对象变为reject状态。抛出的错误对象会被catch方法回调函数接收到。

    async function f() {
      throw new Error('出错了');
    }
    
    f().then(
      v => console.log(v),
      e => console.log(e)
    )
    // Error: 出错了
    

    2)async函数返回的Promise对象,必须等到内部所有await命令的Promise对象执行完,才会发生状态改变。也就是说,只有async函数内部的异步操作执行完,才会执行then方法指定的回调函数。

    下面是一个例子。

    async function getTitle(url) {
      let response = await fetch(url);
      let html = await response.text();
      return html.match(/<title>([\s\S]+)<\/title>/i)[1];
    }
    getTitle('https://tc39.github.io/ecma262/').then(console.log)
    // "ECMAScript 2017 Language Specification"
    

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

    只要一个await语句后面的Promise变为reject,那么整个async函数都会中断执行。

    async function f() {
      await Promise.reject('出错了');
      await Promise.resolve('hello world'); // 不会执行
    }
    

    上面代码中,第二个await语句是不会执行的,因为第一个await语句状态变成了reject。

    为了避免这个问题,可以将第一个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
    

    如果有多个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);
      }
    }
    

    (4)如果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:出错了
    

    上面代码中,async函数f执行后,await后面的Promise对象会抛出一个错误对象,导致catch方法的回调函数被调用,它的参数就是抛出的错误对象。具体的执行机制,可以参考后文的“async函数的实现”。

    防止出错的方法,也是将其放在try...catch代码块之中。

    async function f() {
      try {
        await new Promise(function (resolve, reject) {
          throw new Error('出错了');
        });
      } catch(e) {
      }
      return await('hello world');
    }
    

    ------摘抄记录

    相关文章

      网友评论

          本文标题:async语法

          本文链接:https://www.haomeiwen.com/subject/lsffuhtx.html