TypeScript/JavaScript 中的异步迭代语句
for await...of 是 TypeScript/JavaScript 中的异步迭代语句,专门用于遍历异步可迭代对象(Async Iterable)。
基本语法
for await (const item of asyncIterable) {
// 处理每个异步获取的值
}
与普通 for...of 的区别
| 特性 | for...of |
for await...of |
|---|---|---|
| 迭代对象 | 同步可迭代对象 | 异步可迭代对象 |
| 返回值 | 同步值 | Promise 解析后的值 |
| 使用场景 | 数组、Map、Set等 | 异步流、生成器等 |
使用场景
1. 处理异步生成器函数
async function* asyncGenerator() {
yield await Promise.resolve(1);
yield await Promise.resolve(2);
yield await Promise.resolve(3);
}
async function process() {
for await (const value of asyncGenerator()) {
console.log(value); // 1, 2, 3
}
}
2. 处理多个 Promise 的集合
async function fetchUrls(urls: string[]) {
for await (const response of urls.map(url => fetch(url))) {
const data = await response.json();
console.log(data);
}
}
3. Node.js 流处理
import { createReadStream } from 'fs';
import { createInterface } from 'readline';
async function readLargeFile() {
const fileStream = createReadStream('large-file.txt');
const rl = createInterface({
input: fileStream,
crlfDelay: Infinity
});
for await (const line of rl) {
console.log(line); // 逐行处理大文件
}
}
4. Web Streams API
async function processStream(stream: ReadableStream) {
const reader = stream.getReader();
try {
for await (const chunk of stream) {
console.log('Received chunk:', chunk);
}
} finally {
reader.releaseLock();
}
}
实际示例:批量处理异步任务
// 模拟异步数据源
async function* fetchPaginatedData(pageSize: number = 10) {
let page = 0;
let hasMore = true;
while (hasMore) {
// 模拟 API 调用
const data = await fetchDataFromAPI(page, pageSize);
yield data.items;
hasMore = data.hasMore;
page++;
}
}
async function processAllData() {
const results = [];
for await (const items of fetchPaginatedData()) {
// 等待所有项目的处理完成
const processed = await Promise.all(
items.map(async item => processItem(item))
);
results.push(...processed);
}
return results;
}
注意事项
-
必须在 async 函数中使用
// ❌ 错误:不能在同步函数中使用 function syncFunction() { for await (const item of asyncIterable) { ... } } // ✅ 正确:必须在 async 函数中 async function asyncFunction() { for await (const item of asyncIterable) { ... } } -
错误处理
async function processWithErrorHandling() { try { for await (const item of asyncIterable) { // 处理每个项目 } } catch (error) { console.error('迭代过程中出错:', error); } } -
与 Promise.all() 的区别
for await...of:顺序处理,等待前一个完成Promise.all():并行处理,等待所有完成
底层原理
for await...of 实际上是对异步迭代器的语法糖:
// for await...of 的等价实现
async function manualAsyncIteration(asyncIterable) {
const iterator = asyncIterable[Symbol.asyncIterator]();
try {
while (true) {
const { value, done } = await iterator.next();
if (done) break;
// 使用 value
}
} finally {
if (iterator.return) await iterator.return();
}
}
浏览器和 Node.js 支持
- ES2018+ 标准
- Node.js 10.0.0+ 完全支持
- 现代浏览器支持(除 IE 外)
for await...of 是处理异步数据流的强大工具,特别适合处理分页 API、文件流、WebSocket 消息等场景。
浙公网安备 33010602011771号