ES9 引入了 async/await
,让异步调用变得更加优雅,然而将异步代码转换为同步代码的时候,我们往往会使用生成器函数(Generator
)进行迭代操作。本文将介绍如何解决 ES9 的 Generator
迭代,以便更加优雅地进行异步调用。
什么是 Generator
Generator
是一种可以暂停和恢复执行的函数,它的最大特点就是可以通过 yield
关键字来实现暂停返回值的功能。
举个例子,我们可以用 Generator
实现一个简单的迭代器:
-- -------------------- ---- ------- --------- ------- - --- ---- - - -- - - -- ---- - ----- -- - - ----- --------- - -------- ------------------------------------ -- -- - ------------------------------------ -- -- - ------------------------------------ -- -- - ------------------------------ -- -- - ------ ---------- ----- ---- -
可以看到,Generator
在 yield
关键字处停止了执行,然后将 yield
后面的值返回。每次调用迭代器的 next
方法都会继续执行下一次 yield
。
使用 Generator 进行异步调用
假设我们有一个异步操作需要进行多次调用,并且每次调用必须等待上一次调用完成后才能执行。使用 async/await
可以让代码变得更加优雅:
async function process() { const result1 = await asyncTask1(); const result2 = await asyncTask2(result1); const result3 = await asyncTask3(result2); console.log(result3); }
然而在实际开发中,使用 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