JavaScript 异步之 async-await 写法

8,212 阅读2分钟

「这是我参与2022首次更文挑战的第30天,活动详情查看:2022首次更文挑战」。

写在前面

  • 前面三篇文章,我们分别使用嵌套回掉的方式,自定义事件的方式、promise 的方式完成了涉及异步操作的例子
  • 且前面的方式都或多或少有些不优雅,嵌套回掉容易造成回掉地狱,自定义事件需要引入额外的变量来存储不同事件的ID,promise 的方式倒是解决了前面两个的问题,但是链式操作,回随着我们操作步骤的复杂,而变得很长
  • 今天这篇文章将使用 async-await 的方式,用同步代码的写法,完成异步操作的需求

基于 async-await 的改造

  • async 与 await 通常是搭配使用,await 目前只能用在 async 关键字声明的函数里面,还不支持普通函数内使用和全局环境中使用
  • async 声明的函数一定会返回一个 promise 对象
  • async 与 await 的设计就是为了简化 promise api 的使用,这种以同步代码进行异步操作的行为就好像搭配使用了 generator 和 promise
  • 下面是使用 async-await 改造前面三篇文章所实现的 demo
let move = (ele, direction, target, cb) => {
    return new Promise((resolve) => {
      let fn = () => {
        let start = parseInt(getComputedStyle(ele, null)[direction]);
        let speed = ((target - start) / Math.abs(target - start)) * 2;
        start += speed;
        ele.style[direction] = `${start}px`;

        setTimeout(() => {
          if (Math.abs(target - start) <= 2) {
            ele.style[direction] = `${target}px`;

            // cb & cb();
            resolve();
          } else {
            fn();
          }
        }, 10);
      };

      fn();
    });
};
  • 由于 async-await 也是基于 promise 来实现异步操作的,那么 move 函数就需要与之前 promise 版本的保持一致
  • 需要改变的是 move 函数的调用方式
(async () => {
    await move(ele, "left", 300);
    await move(ele, "top", 300);
    await move(ele, "left", 0);
    await move(ele, "top", 0);
})();
  • 前面也提到了 await 不能直接在全局环境中使用,需要在 async 关键字声明的函数里面进行使用
  • 所以这里使用的是即时函数的自执行的方式去调用的 move 方法
  • 怎么样,这样写代码,是不是很简洁,很优雅

小结

  • 到这里我们基于 async-await 的改造已经完成
  • 前面 3 篇文章加上这篇,我们一步一步,从嵌套回掉的方式,改进到自定义事件的方式,再次改进为 promise 的方式,到最后的 async-await 的实现方式,代码也变得组件优雅起来

最后

  • 今天的分享就到这里了,欢迎大家在评论区里面进行讨论 👏。
  • 如果觉得文章写的不错的话,希望大家不要吝惜点赞,大家的鼓励是我分享的最大动力 🥰