TypeScript 中的迭代器和生成器是用来处理序列的功能强大的工具。迭代器允许对象自定义其迭代行为,而生成器则提供了一种更便捷的方式来定义复杂的迭代逻辑。
1. 迭代器 (Iterators)
定义:迭代器是一个对象,它实现了 Iterator
接口,该接口包含一个 next
方法,返回一个包含 value
和 done
属性的对象。
基本用法:
// 定义一个迭代器
class SimpleIterator {
private count: number = 0;
private limit: number;
constructor(limit: number) {
this.limit = limit;
}
// 实现迭代器协议
next() {
if (this.count < this.limit) {
return { value: this.count++, done: false };
} else {
return { value: undefined, done: true };
}
}
}
const iterator = new SimpleIterator(3);
console.log(iterator.next()); // { value: 0, done: false }
console.log(iterator.next()); // { value: 1, done: false }
console.log(iterator.next()); // { value: 2, done: false }
console.log(iterator.next()); // { value: undefined, done: true }
说明:SimpleIterator
类实现了一个简单的迭代器,它生成从 0
到 limit-1
的值。
2. 可迭代对象 (Iterable)
定义:一个对象被认为是可迭代的,如果它实现了 Iterable
接口,这意味着它有一个 Symbol.iterator
属性,返回一个迭代器。
基本用法:
class NumberRange implements Iterable<number> {
constructor(private start: number, private end: number) {}
[Symbol.iterator]() {
let current = this.start;
const end = this.end;
return {
next() {
if (current < end) {
return { value: current++, done: false };
} else {
return { value: undefined, done: true };
}
}
};
}
}
const range = new NumberRange(1, 4);
for (const num of range) {
console.log(num); // 1, 2, 3
}
说明:NumberRange
类实现了 Iterable
接口,使得其实例可以使用 for...of
循环进行迭代。
3. 生成器 (Generators)
定义:生成器是一种特殊类型的函数,它可以暂停和恢复其执行。生成器函数使用 function*
语法定义,内部使用 yield
表达式来生成值。
基本用法:
function* simpleGenerator() {
yield 1;
yield 2;
yield 3;
}
const generator = simpleGenerator();
console.log(generator.next()); // { value: 1, done: false }
console.log(generator.next()); // { value: 2, done: false }
console.log(generator.next()); // { value: 3, done: false }
console.log(generator.next()); // { value: undefined, done: true }
说明:simpleGenerator
函数每次 yield
一个值,当没有更多值时,返回 { value: undefined, done: true }
。
4. 使用生成器实现可迭代对象
定义和用法:生成器函数可以用于实现 Iterable
接口,使得自定义迭代逻辑更加简单。
class NumberRange {
constructor(private start: number, private end: number) {}
*[Symbol.iterator]() {
for (let i = this.start; i < this.end; i++) {
yield i;
}
}
}
const range = new NumberRange(1, 4);
for (const num of range) {
console.log(num); // 1, 2, 3
}
说明:NumberRange
类使用生成器函数实现了 Iterable
接口,使得迭代逻辑更简洁。
5. 生成器的高级用法
生成器除了简单地生成序列,还可以通过 yield
表达式和 next
方法之间的双向通信,实现更复杂的迭代逻辑。
双向通信:
function* generatorWithInput() {
const first = yield "first yield";
console.log(`Received: ${first}`);
const second = yield "second yield";
console.log(`Received: ${second}`);
}
const generator = generatorWithInput();
console.log(generator.next()); // { value: "first yield", done: false }
console.log(generator.next("first input")); // { value: "second yield", done: false }
// Received: first input
console.log(generator.next("second input")); // { value: undefined, done: true }
// Received: second input
说明:生成器函数 generatorWithInput
演示了如何在调用 next
时向生成器发送值,并在生成器中接收这些值。
6. 异步生成器 (Async Generators)
定义:异步生成器函数使用 async function*
语法定义,允许在生成器函数中使用 await
表达式,从而处理异步操作。
基本用法:
async function* asyncGenerator() {
for (let i = 0; i < 3; i++) {
await new Promise(resolve => setTimeout(resolve, 1000));
yield i;
}
}
(async () => {
for await (const num of asyncGenerator()) {
console.log(num); // 0, 1, 2 (每秒一个)
}
})();
说明:asyncGenerator
异步生成器函数每秒生成一个值,通过 for await...of
循环进行异步迭代。
总结
TypeScript 中的迭代器和生成器提供了强大的工具来处理序列和异步操作:
- 迭代器:通过实现
Iterator
接口自定义迭代行为。 - 可迭代对象:实现
Iterable
接口,使对象可以被for...of
循环迭代。 - 生成器:使用
function*
定义,使用yield
表达式生成值,提供暂停和恢复执行的能力。 - 异步生成器:使用
async function*
定义,允许在生成器中使用异步操作。
通过理解和应用这些特性,你可以编写更加灵活和高效的代码,处理复杂的迭代逻辑和异步操作。