TypeScript中yield和Generator的使用指南
一、引言
在 JavaScript 中,Generator 是一種強大的函數(shù)形式,允許函數(shù)在執(zhí)行過程中“暫停”和“恢復(fù)”。而在 TypeScript 中,Generator 同樣受支持,并且擁有完整的類型推導(dǎo)與定義能力,使得開發(fā)者可以更安全、更清晰地使用這一特性。
本篇文章將系統(tǒng)總結(jié) TypeScript 中如何使用 yield 與 Generator,包括語法、類型定義、應(yīng)用場景和注意事項。
二、什么是 Generator?
Generator 函數(shù)是一種可以 中斷執(zhí)行并返回多個值 的函數(shù)。它以 function* 的形式聲明,通過 yield 表達式逐步“產(chǎn)出”值。
function* simpleGenerator() {
yield 1;
yield 2;
yield 3;
}
調(diào)用 simpleGenerator() 并不會立即執(zhí)行函數(shù)體,而是返回一個 Iterator 對象,通過調(diào)用其 .next() 方法,逐步獲得每一個 yield 的值。
const gen = simpleGenerator();
console.log(gen.next()); // { value: 1, done: false }
console.log(gen.next()); // { value: 2, done: false }
console.log(gen.next()); // { value: 3, done: false }
console.log(gen.next()); // { value: undefined, done: true }
三、在 TypeScript 中使用 Generator
3.1 基本類型定義
TypeScript 可以對 Generator 的返回值、輸入值、return 結(jié)果進行嚴格的類型定義:
function* gen(): Generator<number, string, unknown> {
yield 1;
yield 2;
return "done";
}
上面的泛型參數(shù)含義如下:
Generator<YieldType, ReturnType, NextType>
YieldType: 每次yield返回的值類型ReturnType: 函數(shù)通過return最終返回的值類型NextType: 外部傳入.next(value)的值類型
3.2 接收外部輸入
你可以在 Generator 中通過 yield 表達式接收 .next() 傳入的值:
function* adder(): Generator<string, number, number> {
const a = yield "Please provide a number";
const b = yield "Another number please";
return a + b;
}
const g = adder();
console.log(g.next()); // { value: "Please provide a number", done: false }
console.log(g.next(10)); // { value: "Another number please", done: false }
console.log(g.next(20)); // { value: 30, done: true }
四、Generator 的應(yīng)用場景
4.1 惰性計算(Lazy Evaluation)
function* infiniteCounter(): Generator<number> {
let i = 0;
while (true) {
yield i++;
}
}
適用于需要按需計算而不是一次性生成的場景,比如大數(shù)據(jù)分頁、日志流等。
4.2 數(shù)據(jù)流處理
function* dataStream(data: string[]): Generator<string> {
for (const item of data) {
yield item.toUpperCase();
}
}
可以與 for...of 搭配,實現(xiàn)流式數(shù)據(jù)處理。
4.3 協(xié)程式異步控制(傳統(tǒng)用法)
雖然現(xiàn)代 JavaScript 推薦使用 async/await,但 Generator 曾用于模擬協(xié)程控制流(如 co 庫):
function* flow() {
const result1 = yield fetch("/api/data1");
const result2 = yield fetch(`/api/data2?id=${result1.id}`);
return result2;
}
五、Generator 與 Iterable 協(xié)議
Generator 本身實現(xiàn)了 Iterable 接口,因此可以直接用于 for...of 循環(huán):
function* countdown(n: number) {
while (n > 0) {
yield n--;
}
}
for (const i of countdown(3)) {
console.log(i); // 3, 2, 1
}
也可以使用展開運算符:
console.log([...countdown(3)]); // [3, 2, 1]
六、與異步 Generator 的對比(簡要)
TypeScript 同樣支持 async function* 來創(chuàng)建異步 Generator:
async function* asyncGen(): AsyncGenerator<number> {
for (let i = 0; i < 3; i++) {
await new Promise(res => setTimeout(res, 100));
yield i;
}
}
(async () => {
for await (const n of asyncGen()) {
console.log(n);
}
})();
區(qū)別:
yield可用于同步 Generator;await yield可用于異步 Generator。
七、注意事項
yield不能在普通函數(shù)中使用,只能在function*中使用;- 不同于
return,yield不會結(jié)束函數(shù); - 每次調(diào)用
.next()會推進函數(shù)執(zhí)行到下一個yield; Generator不適合復(fù)雜異步邏輯處理(推薦使用async/await)。
八、總結(jié)
| 功能點 | 是否支持 | 說明 |
|---|---|---|
| function* | ? | 創(chuàng)建一個 Generator 函數(shù) |
| yield | ? | 用于返回值,并暫停函數(shù)執(zhí)行 |
| .next(value) | ? | 繼續(xù)執(zhí)行函數(shù),并傳值進來 |
| 類型定義 | ? | Generator 泛型支持三類類型 |
| 異步 Generator | ? | 支持 async function* |
在 TypeScript 中使用 Generator,可以幫助你實現(xiàn)更加清晰的迭代邏輯和惰性計算模型,尤其在處理數(shù)據(jù)流、實現(xiàn)中間狀態(tài)管理等場景時,具有獨特的優(yōu)勢。
到此這篇關(guān)于TypeScript中yield和Generator的使用指南的文章就介紹到這了,更多相關(guān)TypeScript yield Generator內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
JS拖動鼠標畫出方框?qū)崿F(xiàn)鼠標選區(qū)的方法
這篇文章主要介紹了JS拖動鼠標畫出方框?qū)崿F(xiàn)鼠標選區(qū)的方法,涉及javascript鼠標事件及頁面元素樣式的相關(guān)技巧,具有一定參考借鑒價值,需要的朋友可以參考下2015-08-08
js substr支持中文截取函數(shù)代碼(中文是雙字節(jié))
js substr支持中文截取函數(shù)代碼,中文是雙字節(jié),配有實例需要的朋友可以參考下2013-04-04
JavaScript深度復(fù)制(deep clone)的實現(xiàn)方法
本文給大家介紹JavaScript深度復(fù)制(deep clone)的實現(xiàn)方法,涉及到j(luò)s深度復(fù)制相關(guān)知識,本文介紹的非常詳細,特此分享腳本之家平臺供大家參考2016-02-02
原生javascript實現(xiàn)Tab選項卡切換功能
本文主要介紹了使用原生javascript實現(xiàn)Tab選項卡切換的功能,雖然jQuery有很多類似的插件,單jQuery庫著實有點龐大,這種小功能還是直接用javascript來做就好了。2015-01-01
JavaScript去除空格的三種方法(正則/傳參函數(shù)/trim)
個人認為去除空格最好的方法.采用的是正則表達式,這是最核心的原理,同時呢,還是有其他方法可以辦到的,接下來將介紹一下三種方法(trim)空格,感興趣的朋友可以了解下,或許對你有幫助呢2013-02-02

