在现代的 Web 应用开发中,数据的异步流变得越来越普遍。JavaScript 作为前端开发的主力语言,在帮助我们处理这些异步数据流方面也不断地进行改进。一个很好的例子就是 ECMAScript 2021 中引入的 async generators。它们可以使我们更轻松地处理异步数据流,本文就来具体了解一下。
什么是 async generators?
async generators 是在 ECMAScript 2021 标准中引入的新特性,是 Generator 函数的异步版本。Generator 函数可以迭代生成值,而 async generators 可以迭代生成异步的值。与传统的生成器一样,async generators 可以为我们提供一系列异步事件。同时在每个异步事件完成时,也可以更新下一次异步迭代的参数。
async generators 跟 Generator 函数一样,使用了 function*
关键字来声明一个生成器函数。但是它们还带有异步的特性,使得我们可以使用 await
关键字,从异步的迭代操作中生成异步值。一个典型的 async generator 函数的定义如下:
----- --------- ------------------------ - -- --- -
注意函数名称后紧跟着的 *
符号表示这是一个异步迭代生成器。同时,关键字 async
表示这个生成器可以异步返回值。
Async iterators 和 for-await-of 循环
与传统的 JavaScript 迭代器一样,async generators 可以使用 Symbol.asyncIterator
定义为一个异步迭代器,从而能够使用 for-await-of
语法进行迭代操作。
你可以将 async iterators 看作是带有异步方法的迭代器,实现了 next()
方法返回一个 Promise。默认情况下,async iterators 也应该实现一个同步的迭代器方法 Symbol.iterator
,返回一个对象,它有一个同步的 next() 方法。
举一个例子,我们使用 async generator 返回一组异步的数字:
-- ---- ----- --------- ----- --------- ---------------- - ----- -- ----- -- ----- -- - -- -- ------------ ------- ------ -- -- - --- ----- ------ ------ -- ----------------- - -------------------- -- - - - - -----
我们使用一个 async generator 返回了 1,2 和 3 三个数字,并使用 for-await-of
循环对其进行遍历。注意,由于 async generator 是异步迭代器,因此我们使用了 async () => {...}()
来包装整个循环体,以便我们可以在其内部使用 await
关键字。
async generators 和处理异步数据流
async generators 最有价值的应用是处理异步数据流。这种模式尤其适合用于需要在网络或数据库等异步数据源上的数据处理中。
让我们使用一个简单的例子来说明这个过程。假设我们需要向 API 发起 3 个 HTTP 请求,然后使用 Promise 对象异步获取它们的响应。一旦所有的响应数据都返回,我们想汇总这些数据并进行处理。这个过程可以如下实现:
----- --------- -------------------- - -- ---- - - ---- -- ----- -------- - -------------- -- ------------ -- ---- ------- ----- --- ------ ------- -- --------- - ----- -------- - ----- -------- -- - ------- ------- ----- --------- - ---- - ----- ----- ---------------- - - ------ -- -- - ----- ---- - ------------------------------------------------ ----------------------------------------------- ------------------------------------------------ -- -- ------------ ---- ----- --------- ------ --- ---- - --- --- ----- ------ ---- -- --------------------- - ---- -- ----- - ------------------ -- -- --------------------------- ---------------------------- ---------------------------- -----
这个例子中,我们定义了一个 async generator 函数 fetchResponses()
,它接受一个 URL 数组作为参数,在 for 循环中,我们为异步返回的每个 Promise 提取出响应文本并将它们传递给下一个迭代。最后,我们可以使用 for-await-of
循环对 async generator 进行迭代,并汇总异步返回的所有数据。
总结
async generators 可以帮助我们轻松地处理异步数据流。它们是 ECMAScript 2021 的新特性,是 Generator 函数的异步变种。通过使用 async generators,我们可以将异步的迭代与异步的数据处理结合起来,使得我们能够更加优美地处理异步数据流,并更容易地访问异步数据源。
参考文献
- "Async Iterators and Generators - An Introduction" by Aaron Powell: https://www.telerik.com/blogs/async-iterators-and-generators-an-introduction.
- "ES2018: Asynchronous Iteration with for-await-of and yield*" by Axel Rauschmayer: https://2ality.com/2016/10/asynchronous-iteration.html.
- "ES2018: RegExp Lookbehind Assertions" by Axel Rauschmayer: https://2ality.com/2017/05/regexp-lookbehind-assertions.html.
来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/66456c44d3423812e4363089