返回

async/await 的简洁实现

前端

尽管 JavaScript 是一种单线程语言,但它可以通过异步编程来处理并发任务。在过去的几年中,async/await 语法已经成为编写异步代码的标准方式,它比传统的回调和 Promise 更简洁、更易于阅读。

async 的本质

async 是一个,用于声明一个异步函数。它允许函数返回一个 Promise,但语法更像同步函数。

例如,以下是一个使用 async 定义的函数,它使用 setTimeout 异步地设置一个值:

async function setValue() {
  const value = await setTimeout(() => 100, 1000);
  return value;
}

async 相较于 Generator 函数的优势

async/await 之前,Generator 函数是编写异步代码的常见方法。Generator 函数允许函数在不阻塞的情况下暂停并恢复执行。

然而,async/await 提供了几个优势:

  • 更简洁的语法: async/await 比 Generator 函数更易于阅读和编写。
  • 更好的错误处理: async/await 使用 try/catch 语句处理错误,这比 Generator 函数中的 yield* 语句更简洁。
  • 更好的可组合性: async/await 函数可以像同步函数一样组合,这使得编写可重用的代码更容易。

实现

async/await 语法由 JavaScript 引擎实现,它将 async 函数转换为 Generator 函数并使用 Promise 管理执行。

以下是一个用 JavaScript 引擎实现的 async 函数的简化版本:

function asyncToGenerator(fn) {
  return function() {
    const generator = fn.apply(this, arguments);
    return new Promise((resolve, reject) => {
      function step(key, arg) {
        try {
          const { value, done } = generator.next(arg);
          if (done) {
            resolve(value);
          } else {
            Promise.resolve(value).then(
              (val) => step("next", val),
              (err) => step("throw", err)
            );
          }
        } catch (err) {
          reject(err);
        }
      }
      step("next");
    });
  };
}

结论

async/await 语法为 JavaScript 中的异步编程提供了简洁、易读且强大的方式。它相对于 Generator 函数具有优势,并且由 JavaScript 引擎本身实现。

通过使用 async/await,开发人员可以编写更具可读性、可维护性和可重用性的异步代码。