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 頻道。