TypeScript 迭代器
最后修改时间:2025年3月3日
TypeScript 中的迭代器提供了一种遍历数组、Map 和 Set 等集合的方式。它们实现了 Iterable 和 Iterator 协议,支持自定义迭代逻辑。本教程将探讨迭代器、生成器和实际示例。
基本迭代器协议
迭代器必须实现 next() 方法,该方法返回一个具有 value 和 done 属性的对象。此示例展示了一个简单的迭代器。
basic_iterator.ts
const numbers = [1, 2, 3];
const iterator = numbers[Symbol.iterator]();
console.log(iterator.next()); // { value: 1, done: false }
console.log(iterator.next()); // { value: 2, done: false }
console.log(iterator.next()); // { value: 3, done: false }
console.log(iterator.next()); // { value: undefined, done: true }
Symbol.iterator 方法返回一个迭代器对象。next() 方法推进迭代器并返回当前值。
自定义迭代器
您可以通过实现 Iterable 接口来创建自定义迭代器。此示例定义了一个自定义范围迭代器。
custom_iterator.ts
class Range implements Iterable<number> {
constructor(private start: number, private end: number) {}
[Symbol.iterator](): Iterator<number> {
let current = this.start;
return {
next: () => {
return current <= this.end
? { value: current++, done: false }
: { value: undefined, done: true };
}
};
}
}
const range = new Range(1, 3);
for (const num of range) {
console.log(num); // Output: 1, 2, 3
}
Range 类实现了 Iterable 接口。Symbol.iterator 方法返回一个迭代器对象。
生成器
生成器使用 function* 语法简化了迭代器的创建。它们自动实现迭代器协议。
generator.ts
function* generateSequence(start: number, end: number) {
for (let i = start; i <= end; i++) {
yield i;
}
}
const sequence = generateSequence(1, 3);
for (const num of sequence) {
console.log(num); // Output: 1, 2, 3
}
yield 关键字会暂停执行并返回值。生成器非常适合惰性求值。
遍历 Map
Map 默认是可迭代的。此示例演示了如何遍历 Map 的键、值和条目。
map_iterator.ts
const map = new Map([
['a', 1],
['b', 2],
['c', 3]
]);
for (const [key, value] of map) {
console.log(`${key}: ${value}`); // Output: a: 1, b: 2, c: 3
}
Map 提供了键、值和条目的内置迭代器。使用解构来访问键值对。
遍历 Set
Set 也是可迭代的。此示例展示了如何遍历 Set 的值。
set_iterator.ts
const set = new Set([1, 2, 3]);
for (const value of set) {
console.log(value); // Output: 1, 2, 3
}
Set 存储唯一值并提供简单的迭代器进行遍历。
异步迭代器
异步迭代器支持异步数据遍历。此示例使用异步生成器来获取数据。
async_iterator.ts
async function* fetchData(urls: string[]) {
for (const url of urls) {
const response = await fetch(url);
yield response.json();
}
}
(async () => {
const urls = ['https://api.example.com/data1', 'https://api.example.com/data2'];
for await (const data of fetchData(urls)) {
console.log(data);
}
})();
异步迭代器使用 for await...of 来处理异步数据流。它们对于 API 和数据库很有用。
组合迭代器
您可以使用实用函数组合多个迭代器。此示例将两个数组合并到一个迭代器中。
combine_iterators.ts
function* mergeIterators<T>(...iterators: Iterable<T>[]) {
for (const iterator of iterators) {
yield* iterator;
}
}
const merged = mergeIterators([1, 2], [3, 4]);
for (const num of merged) {
console.log(num); // Output: 1, 2, 3, 4
}
yield* 关键字将迭代委托给另一个可迭代对象。这种模式对于组合数据源很有用。
最佳实践
- 使用生成器:自定义迭代器首选生成器
- 惰性求值:利用惰性求值来提高性能
- 异步迭代器:异步数据使用异步迭代器
- 组合迭代器:合并迭代器以实现复杂数据流
- 类型安全:确保迭代器返回一致的类型
来源
本教程通过实际示例涵盖了 TypeScript 迭代器。使用这些模式来高效处理集合和异步数据。