TypeScript 中的生成器函数
本文解释了 TypeScript 中的生成器函数。
您可以学习从生成器函数的使用基础到与异步处理结合的高级示例,以及相关的代码示例。
YouTube Video
生成器函数
TypeScript 中的生成器函数提供了与 JavaScript 生成器函数类似的功能。生成器函数使用 function*(带星号的函数声明)定义,是一种特殊的函数,可以暂停和恢复执行,而不像普通函数那样直接运行到底。
调用生成器函数时,会返回一个 迭代器,该迭代器通过 yield 关键字生成值并暂停执行,还可以从外部传递值进入生成器。
生成器函数的基本语法
1function* myGenerator(): Generator<number, void, unknown> {
2 yield 1;
3 yield 2;
4 yield 3;
5}
6
7const gen = myGenerator();
8
9console.log(gen.next().value); // 1
10console.log(gen.next().value); // 2
11console.log(gen.next().value); // 3
12console.log(gen.next().done); // true (Iteration finished)
- 使用
function* myGenerator()定义一个生成器函数。 yield关键字在返回一个值的同时暂停函数的执行。- 每次调用
next()方法时,生成器函数的执行都会恢复并继续运行至下一个yield。
next() 方法返回一个包含下一个值和 done 属性的对象。当 done 为 true 时,表示所有值已经生成,生成器处理已完成。
生成器函数的应用
使用生成器函数可以轻松地表示顺序处理。在以下示例中,我们创建了一个生成器函数来生成一系列的数字。
1function* sequenceGenerator(start: number = 0, step: number = 1) {
2 let current = start;
3 while (true) {
4 yield current;
5 current += step;
6 }
7}
8
9const seq = sequenceGenerator(1, 2);
10
11console.log(seq.next().value); // 1
12console.log(seq.next().value); // 3
13console.log(seq.next().value); // 5
- 在此示例中,
sequenceGenerator生成了一个无限递增的数字序列。使用yield在每一步返回一个值,并在后续调用时生成下一个值。
向 next 传递值
next() 方法可以接收一个值,该值可以传递到生成器函数中。
1function* adder() {
2 const num1 = yield;
3 const num2 = yield;
4 yield num1 + num2;
5}
6
7const addGen = adder();
8addGen.next(); // Initialization
9addGen.next(5); // Set 5 to num1
10const result = addGen.next(10).value; // Set 10 to num2 and get result
11console.log(result); // 15
- 在此示例中,
next(5)和next(10)将各自的值传递到生成器函数中,而yield num1 + num2返回它们的和。
return 和 throw
return(value)可以终止生成器并返回指定的值。throw(error)可以在生成器内部抛出异常,用于在生成器中处理异常。
1function* testGenerator() {
2 try {
3 yield 1;
4 yield 2;
5 } catch (e) {
6 console.error("Error caught:", e);
7 }
8}
9
10const gen = testGenerator();
11console.log(gen.next().value); // 1
12gen.throw(new Error("An error occurred!")); // Error caught: An error occurred!
- 在此示例中,使用
throw方法在生成器内部生成一个错误,并在生成器中捕获该错误。
TypeScript中的类型定义
生成器函数的类型定义可以用以下格式指定。
1// Generator<YieldType, ReturnType, NextType>
2function* myGenerator(): Generator<number, void, unknown> {
3 yield 1;
4 yield 2;
5 yield 3;
6}- 您可以使用
Generator<YieldType, ReturnType, NextType>的形式指定类型。YieldType是yield返回值的类型。ReturnType是return返回值的类型。NextType是传递给next()的值的类型。
在以下示例中,指定了特定类型以便安全地使用带有类型的生成器。
1function* numberGenerator(): Generator<number, void, number> {
2 const num1 = yield 1;
3 const num2 = yield num1 + 2;
4 yield num2 + 3;
5}
6
7const gen = numberGenerator();
8
9console.log(gen.next().value); // 1
10console.log(gen.next(10).value); // 12 (10 + 2)
11console.log(gen.next(20).value); // 23 (20 + 3)
生成器与异步处理
生成器也可以用于异步处理。例如,您可以使用yield等待异步操作的结果,同时继续进行顺序处理。然而,在TypeScript或JavaScript中,async/await更为常用。
1function* asyncTask() {
2 const result1 = yield fetch("https://codesparklab.com/json/example1.json");
3 console.log(result1);
4
5 const result2 = yield fetch("https://codesparklab.com/json/example2.json");
6 console.log(result2);
7}因此,尽管可以使用生成器顺序处理异步操作,但由于Promises和async/await更为方便,它们并不常被用于异步处理。
总结
- 生成器函数是使用
function*定义的特殊函数,它可以通过yield返回值,同时暂停函数的执行。 - 使用**
next()**恢复生成器并接收值。此外,您可以使用next(value)将值发送到生成器中。 - 您可以使用**
return()和throw()**终止生成器函数或处理错误。 - 在TypeScript中使用生成器时,您可以利用类型定义编写类型安全的代码。
生成器是强大的工具,允许您灵活地控制迭代。
您可以在我们的YouTube频道上使用Visual Studio Code跟随上述文章进行学习。 请也查看我们的YouTube频道。