在 JavaScript 中,异步编程特别重要,因为它可以让我们在请求资源时不会阻塞线程。ES6 中添加了生成器函数,这种函数可以用来更方便地写异步代码。本文将介绍 ES6 中的生成器函数以及如何使用它们进行异步编程。
生成器函数
生成器函数是 ES6 中新增的一种函数类型,它可以用来创建生成器对象。生成器函数与普通函数的不同之处在于,普通函数一旦开始执行就会一直执行到结束,而生成器函数可以在执行时暂停并再次恢复执行。这个特点使得生成器函数在编写异步代码时非常有用。
生成器函数的语法如下所示:
function* generatorFunction() { // ... }
其中 function*
可以被看作是 function
的一个扩展形式,可以用来声明一个生成器函数,函数体中包含 yield
关键字,表示当前执行的位置可以被暂停。
yield 关键字
在生成器函数中,yield
是用来指示执行暂停的关键字。当遇到 yield
时,函数体会停止执行并将控制权交还给函数调用者。此时,调用者可以做一些其他操作,之后再恢复执行函数,函数将从上次暂停的地方继续执行。
下面是一个例子,展示了如何在生成器函数中使用 yield
:
-- -------------------- ---- ------- --------- ------------------- - ------------------- -------- ------ ------------------ -------- - ----- --------- - -------------------- ----------------- --------------- ---------- -----------------
输出:
Before yield In between After yield
在上面的例子中,我们定义了一个生成器函数,其中包含两条 console.log
语句和一条 yield
语句。调用 generatorFunction()
会返回一个生成器对象,我们可以通过该对象的 next()
方法来执行函数。
首先,我们执行 generator.next()
,开始执行函数。执行到 yield
语句时函数会暂停并返回一个包含 { value: undefined, done: false }
的对象。我们在控制台中输出了一个字符串 In between
,然后再次调用 generator.next()
。此时,函数从上次暂停的地方继续执行,并在执行完最后一条语句后结束了,返回一个包含 { value: undefined, done: true }
的对象。
异步编程示例
在下面这个示例中,我们从网络上获取一张图片,并把它显示在页面上。在这个过程中,使用了一个生成器函数和一个异步操作。
-- -------------------- ---- ------- --------- ----------- - ----- -------- - ----- ----------------------------------- ----- ---- - ----- ---------------- ----- --- - -------------------------- ----- --- - ------------------------------ ------- - ---- ------------------------------- - -------- --------------------------------- - ----- --------- - -------------------- -------- -------------------- - -- ------------- ------- ------------ --------- -- ---------------------------------- ---------- -- ---------------------- - --- - ------------------------------- - ----- ----- - --------------------- - - --------------------------
在上面的示例中,我们首先定义了一个名为 loadImage
的生成器函数,它不断地使用 yield
语句来暂停函数的执行,最后显示图片。
我们还定义了一个名为 asyncGenerator
的函数,它接受一个生成器函数作为参数,并使用 fetch
异步函数来获取图片数据。当获取到响应时,我们使用 yield
暂停函数的执行,并将响应对象作为 yield
的值。在下一个 yield
语句中,我们提取响应中的二进制数据并转换为图片 URL。最后,我们将图片显示在屏幕上。
asyncGenerator
函数会在 loadImage
函数中不断地执行 yield
语句,并将结果传递给 handleResult
函数。如果函数中的 yield
语句返回一个 promise,我们需要等待 promise 完成,并将结果作为下一个 yield
语句的值传递给 generator.next()
。如果 promise 产生了错误,我们将其作为异常传递给生成器函数。
在示例代码中,我们使用了 asyncGenerator(loadImage)
去执行 loadImage
函数,使得它最终会将图片在页面上显示出来。
总结
在本文中,我们介绍了 ES6 中的生成器函数以及它们如何用于编写异步代码。我们还展示了一个使用生成器函数的示例代码,并详细说明了异步操作如何在生成器函数中实现。生成器函数是一种非常强大的工具,可以使得异步编程变得更加简单明了。在进行异步编程时,使用生成器函数会比使用回调函数或 promise 更加优雅,代码逻辑也更加清晰易懂。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/64c863ed5ad90b6d041373a6