解决 ES9 的 Generator 迭代,让异步调用更加优雅

阅读时长 5 分钟读完

ES9 引入了 async/await,让异步调用变得更加优雅,然而将异步代码转换为同步代码的时候,我们往往会使用生成器函数(Generator)进行迭代操作。本文将介绍如何解决 ES9 的 Generator 迭代,以便更加优雅地进行异步调用。

什么是 Generator

Generator 是一种可以暂停和恢复执行的函数,它的最大特点就是可以通过 yield 关键字来实现暂停返回值的功能。

举个例子,我们可以用 Generator 实现一个简单的迭代器:

-- -------------------- ---- -------
--------- ------- -
  --- ---- - - -- - - -- ---- -
    ----- --
  -
-

----- --------- - --------
------------------------------------ -- -- -
------------------------------------ -- -- -
------------------------------------ -- -- -
------------------------------ -- -- - ------ ---------- ----- ---- -

可以看到,Generatoryield 关键字处停止了执行,然后将 yield 后面的值返回。每次调用迭代器的 next 方法都会继续执行下一次 yield

使用 Generator 进行异步调用

假设我们有一个异步操作需要进行多次调用,并且每次调用必须等待上一次调用完成后才能执行。使用 async/await 可以让代码变得更加优雅:

然而在实际开发中,使用 async/await 可能会遇到一些麻烦。例如在 for 循环中使用 await,需要使用一个 wrapper 函数:

-- -------------------- ---- -------
----- -------- --------- -
  --- ---- - - -- - - -- ---- -
    ----- ------ - ----- -------------
    --------------------
  -
-

----- -------- --------- -
  ----- ----------
-

这样会多写一个 wrapper 函数,让代码变得更加复杂。此时可以使用 Generator 来简化代码:

-- -------------------- ---- -------
--------- --------- -
  ----- ------- - ----- -------------
  ----- ------- - ----- --------------------
  ----- ------- - ----- --------------------
  ---------------------
-

-------- -------------- -
  ----- -------- - ------------

  -------- --------- ------ ---- -- -
    -- ------ -
      -------
    -
    ------------------- -- -
      -------------------------------
    ---
  -

  -------------------------
-

-------------

在这个例子中,异步任务被封装在 yield 语句中,通过 run 函数逐步迭代执行。每执行一步异步任务,就调用一次 iterate 函数,当迭代完成后,通过 done 判断是否继续迭代。

解决 ES9 的 Generator 迭代

由于 Generator 对象在执行过程中始终处于暂停状态,因此无法用 try-catch 来捕获 Generator 函数中的错误。为了解决这个问题,ES9 引入了一个新的方法:await 可以直接在 Generator 函数中使用。

在使用 await 的同时,我们需要将异步任务包装在一个 Promise 中,以便异步任务完成后能够被 await 从而继续执行。

-- -------------------- ---- -------
----- -------- --------- -
  --- -
    ----- ------- - ----- ------------------------------
    ----- ------- - ----- -------------------------------------
    ----- ------- - ----- -------------------------------------
    ---------------------
  - ----- ------- -
    ---------------------
  -
-

这样可以使代码整洁优雅,并且使用 try-catch 捕获错误非常方便。

总结

通过解决 ES9 的 Generator 迭代,我们可以使异步调用变得更加优雅,同时也可以使用 try-catch 捕获错误。Generator 对象可以暂停和恢复执行,使用 yield 关键字来实现暂停返回值的功能。在使用 Generator 进行异步调用时,需要使用一个 wrapper 函数或者自己实现迭代器。使用 await 可以直接在 Generator 函数中使用,并且在封装异步任务时需要使用 Promise 对象。

希望本文能够对你在使用 Generator 迭代时有所帮助。

来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/6503112d95b1f8cacd02b3d7

纠错
反馈