随着异步数据源变得普遍(如分页API、数据库流、WebSocket消息),我们需要一种方式来顺序消费那些值不会立即就绪的序列。Async迭代器正是为解决此问题而生,它允许你使用for await...of循环来遍历异步产生的数据。
![图片[1]-什么是async迭代器?-速码派](http://www.sumapai.com/wp-content/uploads/2026/01/48b7b8d01bc84a96ac81ed262e85cf5f_tplv-tb4s082cfz-aigc_resize_1080_1080-1024x683.webp)
Async迭代器协议
一个对象要成为异步可迭代对象,它必须实现[Symbol.asyncIterator]方法。这个方法返回一个异步迭代器对象。异步迭代器与普通迭代器类似,但其next()方法返回一个Promise,该Promise解决后返回{ value, done }形式的迭代结果。
const asyncIterable = {
[Symbol.asyncIterator]() {
let count = 0;
return {
async next() {
await new Promise(resolve => setTimeout(resolve, 100));
if (count < 3) {
return { value: count++, done: false };
}
return { done: true };
}
};
}
};
在这个例子中,每次调用next()都会等待100毫秒后返回下一个值,模拟了异步数据的产生。
使用for await…of循环消费
for await...of循环是专门为异步可迭代对象设计的。它会自动处理异步迭代器返回的Promise,并在值可用时将其赋值给循环变量。
async function process() {
for await (const value of asyncIterable) {
console.log(value); // 依次输出 0, 1, 2,中间有间隔
}
}
process();
循环会一直等待每次next()调用返回的Promise解决,直到遇到done: true。这使得异步数据的消费代码看起来和遍历同步数组一样直观。
使用异步生成器函数
手动实现[Symbol.asyncIterator]和next()方法很繁琐。异步生成器函数为此提供了语法糖。在function关键字前加async,并在函数体内使用yield来产生值,这个函数就会自动返回一个异步可迭代对象。
async function* asyncGenerator() {
for (let i = 0; i < 3; i++) {
await new Promise(resolve => setTimeout(resolve, 100));
yield i;
}
}
async function run() {
const asyncIterable = asyncGenerator(); // 调用生成器返回异步可迭代对象
for await (const num of asyncIterable) {
console.log(num); // 依次输出 0, 1, 2
}
}
run();
异步生成器极大地简化了异步迭代器的创建。yield可以返回一个值,并且函数可以在yield或await处暂停,等待异步操作完成。
实际应用场景
Async迭代器非常适合处理分页API。你可以创建一个异步生成器,在每次迭代中自动获取下一页数据。
async function* fetchPages(url) {
let nextUrl = url;
while (nextUrl) {
const response = await fetch(nextUrl);
const data = await response.json();
yield data.items;
nextUrl = data.nextPage; // 假设API响应中包含下一页链接
}
}
// 像处理本地数组一样处理所有分页数据
for await (const pageItems of fetchPages('/api/items?page=1')) {
for (const item of pageItems) {
console.log(item);
}
}
它们也常用于处理Node.js的Readable流(流在v10之后本身就是异步可迭代的)、WebSocket消息或任何需要按顺序异步消费的数据序列。Async迭代器将异步数据源抽象为统一的拉取模型,让异步数据流处理变得优雅而强大。




















暂无评论内容