JavaScript 异步迭代器
在 JavaScript 中,异步迭代器是一种处理异步数据流的机制。它们通过实现 Symbol.asyncIterator
协议,允许逐项处理需要等待的操作(如网络请求或文件读取)。以下是关键概念和具体实现示例:
标准同步迭代器
通过 Symbol.iterator
实现,next()
返回 { value, done }
对象:
javascript
const syncIter = {
data: [1, 3, 5],
[Symbol.iterator]() {
let index = 0
return {
next: () => index < this.data.length
? { value: this.data[index++], done: false }
: { done: true }
}
}
}
for (const num of syncIter) {
console.log(num) // 依次输出 1, 3, 5
}
生成器函数
用 function*
创建惰性求值的迭代器,通过 yield
暂停执行:
javascript
function* genFibonacci() {
let [a, b] = [0, 1]
while (true) {
yield a
;[a, b] = [b, a + b]
}
}
const fib = genFibonacci()
console.log(fib.next().value) // 0
console.log(fib.next().value) // 1
console.log(fib.next().value) // 1
异步迭代器
通过 Symbol.asyncIterator
实现,next()
返回 Promise<{ value, done }>
:
javascript
const asyncPageFetcher = {
async *[Symbol.asyncIterator]() {
let page = 1
while (true) {
const res = await fetch(`https://api.example.com/data?page=${page}`)
const data = await res.json()
if (data.length === 0) break
yield data
page++
}
}
}
// 使用方式
(async () => {
for await (const pageData of asyncPageFetcher) {
console.log('Received page:', pageData)
}
})()
异步生成器函数
用 async function*
定义,结合 await
和 yield
处理异步操作:
javascript
async function* asyncTimer(interval) {
let count = 0
while (count < 5) {
await new Promise(res => setTimeout(res, interval))
yield `Tick ${++count} at ${new Date().toISOString()}`
}
}
// 消费异步生成器
(async () => {
const timer = asyncTimer(1000)
for await (const msg of timer) {
console.log(msg) // 每秒输出一条带时间戳的消息
}
})()
关键差异对比
特性 | 同步迭代器 | 异步迭代器 |
---|---|---|
接口标识符 | Symbol.iterator | Symbol.asyncIterator |
next() 返回值 | { value, done } | Promise<{ value, done }> |
遍历语法 | for...of | for await...of |
适用场景 | 内存数据、同步计算 | 网络请求、文件流 |
实际应用中,异步迭代器常用于处理以下场景:
- 分页 API 的连续请求
- 大文件流式读取(如 Node.js 的
fs.createReadStream
) - WebSocket 消息的实时监听
- 数据库查询结果的逐批获取
当需要将现有同步迭代器转换为异步版本时,可通过 async function*
包装:
javascript
async function* toAsyncIter(syncIterable) {
for (const item of syncIterable) {
yield await Promise.resolve(item)
}
}
【JavaScript】异步迭代器(Async Iterator):https://segmentfault.com/a/1190000040669160