对async/await的理解

318 阅读3分钟

做一个总结和学习跟大家分享,希望对大家也有所帮助,共同成长进步💪~
如果大家喜欢,可以点赞或留言哈💕~~~~,谢谢大家⭐️⭐️⭐️~~~

async/await是什么?

async 其实呢就是 Generator 函数的语法糖,是用于申明一个function函数是异步的,使得异步操作变得更加方便;

await 直译为等待,它是等待一个异步方法执行完成的。

async和await的基础使用

async 表示这是一个async函数, await只能用在async函数里面,不能单独使用

async 返回的是一个Promise对象,await就是等待这个promise的返回结果后,再继续执行后面的语句

await 等待的是一个Promise对象,后面必须跟一个Promise对象,但是不必写then(),直接就可以得到返回值

async/await的优点

  • 方便级联调用:即调用依次发生的场景;
  • 同步代码编写方式:Promise使用then函数进行链式调用,一直点点点,是一种从左向右的横向写法;async/await从上到下,顺序执行,就像写同步代码一样,更符合代码编写习惯;
  • 多个参数传递:Promise的then函数只能传递一个参数,虽然可以通过包装成对象来传递多个参数,但是会导致传递冗余信息,频繁的解析又重新组合参数,比较麻烦;async/await没有这个限制,可以当做普通的局部变量来处理,用let或者const定义的块级变量想怎么用就怎么用,想定义几个就定义几个,完全没有限制,也没有冗余工作;
  • 同步代码和异步代码可以一起编写:使用Promise的时候最好将同步代码和异步代码放在不同的then节点中,这样结构更加清晰;async/await整个书写习惯都是同步的,不需要纠结同步和异步的区别,当然,异步过程需要包装成一个Promise对象放在await关键字后面;
  • async/await是对Promise的优化:async/await是基于Promise的,是进一步的一种优化,不过在写代码时,Promise本身的API出现得很少,很接近同步代码的写法。

使用注意点

第一点,await命令后面的Promise对象,运行结果可能是rejected,所以最好把await命令放在try...catch代码块中。

第二点,多个await命令后面的异步操作,如果不存在继发关系,最好让它们同时触发。

let foo = await getFoo();
let bar = await getBar();

第三点,await命令只能用在async函数之中,如果用在普通函数,就会报错。

async function dbFuc(db) {
  let docs = [{}, {}, {}];

  // 报错
  docs.forEach(function (doc) {
    await db.post(doc);
  });
}

第四点,async 函数可以保留运行堆栈。

使用场景

async主要来处理异步的操作

假设一个业务,分多个步骤完成,每个步骤都是异步的,而且依赖于上一个步骤的结果那我们就可以使用async了。

async 函数的实现原理

async 函数的实现原理,就是将 Generator 函数和自动执行器,包装在一个函数里。

async function fn(args) {
  // ...
}

// 等同于

function fn(args) {
  return spawn(function* () {
    // ...
  });
}

所有的async函数都可以写成上面的第二种形式,其中的spawn函数就是自动执行器。

下面给出spawn函数的实现,基本就是前文自动执行器的翻版。

function spawn(genF) {
  return new Promise(function(resolve, reject) {
    const gen = genF();
    function step(nextF) {
      let next;
      try {
        next = nextF();
      } catch(e) {
        return reject(e);
      }
      if(next.done) {
        return resolve(next.value);
      }
      Promise.resolve(next.value).then(function(v) {
        step(function() { return gen.next(v); });
      }, function(e) {
        step(function() { return gen.throw(e); });
      });
    }
    step(function() { return gen.next(undefined); });
  });
}

如果大家喜欢,欢迎点赞或留言哈💕~~~~,谢谢大家⭐️⭐️⭐️~~~