Asynchronous Iteration S4
中文标题:异步迭代
- 阶段: Stage 4
- 状态: 已完成
- ECMAScript 版本: ES2018
- 同步时间: 2026年8月26日
- English original · 官方仓库
该提案引入了 AsyncIterator 接口、for-await-of 语句和异步生成器函数来处理异步数据源。它解决了同步迭代器在表示异步数据方面的局限性。
以下 README 来自上游仓库,其中的阶段或状态标注可能滞后;当前信息以提案概览为准。
JavaScript 的异步迭代器
概述和动机
迭代器接口(在 ECMAScript 2015 中引入)是一种顺序数据访问协议,它使得通用且可组合的数据消费者和转换器的开发成为可能。它们的主要接口是一个 next() 方法,该方法返回一个 { value, done } 元组,其中 done 是一个布尔值,指示是否已到达迭代器的末尾,而 value 是序列中产出的值。
由于序列中的下一个值和数据源的“完成”状态都必须在迭代器方法返回时已知,因此迭代器仅适用于表示同步数据源。虽然 JavaScript 程序员遇到的许多数据源是同步的(例如内存中的列表和其他数据结构),但许多其他数据源则不是。例如,任何需要 I/O 访问的数据源通常都会使用基于事件或流式的异步 API 来表示。不幸的是,迭代器不能用于表示此类数据源。
(即使是一个 promise 的迭代器也是不够的,因为它只允许异步确定值,但要求同步确定“完成”状态。)
为了为异步数据源提供通用的数据访问协议,我们引入了 AsyncIterator 接口、异步迭代语句(for-await-of)以及异步生成器函数。
异步迭代器和异步可迭代对象
异步迭代器与迭代器非常相似,只是它的 next() 方法返回一个 { value, done } 对的 promise。如上所述,我们必须返回迭代器结果对的 promise,因为在迭代器方法返回时,迭代器的下一个值和“完成”状态都是未知的。
此外,我们引入一个新的符号用于从给定对象获取异步迭代器,Symbol.asyncIterator。这允许任意对象声明它们是 async iterables,类似于 Symbol.iterator 允许你声明是普通的同步可迭代对象。一个可能使用此功能的类的例子是可读流。
异步迭代器概念中隐含着一个请求队列的概念。由于迭代器方法在先前请求的结果解决之前可以被多次调用,因此每个方法调用必须在内部排队,直到所有先前的请求操作完成。
异步迭代语句:for-await-of
我们引入了 for-of 迭代语句的一个变体,它遍历异步可迭代对象。一个示例用法是:
异步 for-of 语句只允许在异步函数和异步生成器函数中使用(后者见下文)。
在执行期间,使用 [Symbol.asyncIterator]() 方法从数据源创建一个异步迭代器。
每次我们访问序列中的下一个值时,我们隐式地 await 迭代器方法返回的 promise。
异步生成器函数
异步生成器函数类似于生成器函数,但有以下区别:
- 被调用时,异步生成器函数返回一个对象,即一个 async generator,其方法(
next、throw和return)返回{ value, done }的 promise,而不是直接返回{ value, done }。这自动使得返回的异步生成器对象成为 async iterators。 - 允许使用
await表达式和for-await-of语句。 yield*的行为被修改为支持委托给异步可迭代对象。
例如:
这个函数然后返回一个异步生成器对象,该对象可以使用前面示例中所示的 for-await-of 来消费。
实现状态
原生实现
- Chakra: 待解决问题
- JavaScriptCore: 在 Safari Tech Preview 40 中发布
- SpiderMonkey: 在 Firefox 57 中发布;启动 bug
- V8: 在 Chrome 63 中发布;启动 bug