定義
ES6 提供的一種異步編程解決方案
有多種理解角度:
- 語(yǔ)法上,首先可以把它理解成,
Generator函數(shù)是一個(gè)狀態(tài)機(jī),封裝了多個(gè)內(nèi)部狀態(tài)。 - 執(zhí)行
Generator函數(shù)會(huì)返回一個(gè)遍歷器對(duì)象,是Iterator的一種實(shí)現(xiàn),也就是說(shuō),Generator函數(shù)除了狀態(tài)機(jī),還是一個(gè)遍歷器對(duì)象生成函數(shù) - 形式上,
Generator函數(shù)是一個(gè)普通函數(shù)(不能當(dāng)構(gòu)造器函數(shù)使用),但是有兩個(gè)特征:-
function關(guān)鍵字與函數(shù)名之間有一個(gè)星號(hào); - 函數(shù)體內(nèi)部使用
yield表達(dá)式,定義不同的內(nèi)部狀態(tài)(yield在英語(yǔ)里的意思就是“產(chǎn)出”)。
-
調(diào)用與執(zhí)行
Generator 函數(shù)的調(diào)用方法與普通函數(shù)一樣,在函數(shù)名后面加上一對(duì)圓括號(hào)。不同的是,調(diào)用 Generator 函數(shù)后,該函數(shù)并不執(zhí)行,返回的也不是函數(shù)運(yùn)行結(jié)果,而是一個(gè)指向內(nèi)部狀態(tài)的指針對(duì)象,也就是遍歷器對(duì)象(Iterator Object),不是this對(duì)象(獲取不到Generator 函數(shù)里面定義的屬性)。
下一步,必須調(diào)用遍歷器對(duì)象的next方法,使得指針移向下一個(gè)狀態(tài)。也就是說(shuō),每次調(diào)用next方法,內(nèi)部指針就從函數(shù)頭部或上一次停下來(lái)的地方開(kāi)始執(zhí)行,直到遇到下一個(gè)yield表達(dá)式(或return語(yǔ)句)為止。換言之,Generator 函數(shù)是分段執(zhí)行的,yield表達(dá)式是暫停執(zhí)行的標(biāo)記,而next方法可以恢復(fù)執(zhí)行。
yield表達(dá)式
yield表達(dá)式是Generator 函數(shù)的暫停標(biāo)志。遇到yield表達(dá)式,就暫停執(zhí)行后面的操作,并將緊跟在yield后面的那個(gè)表達(dá)式的值,作為返回的對(duì)象的value屬性值。
yield表達(dá)式本身沒(méi)有返回值,或者說(shuō)總是返回undefined。next方法可以帶一個(gè)參數(shù),該參數(shù)就會(huì)被當(dāng)作上一個(gè)yield表達(dá)式的返回值。
方法
-
next():使得指針移向下一個(gè)狀態(tài),返回一個(gè)對(duì)象,這個(gè)對(duì)象包含兩個(gè)屬性:value和done,value屬性表示本次yield表達(dá)式的返回值,done屬性為布爾類型,表示生成器后續(xù)是否還有yield語(yǔ)句,即生成器函數(shù)是否已經(jīng)執(zhí)行完畢并返回。 -
throw():在函數(shù)體外拋出錯(cuò)誤,然后在Generator函數(shù)體內(nèi)捕獲。 -
return():返回給定的值,并且終結(jié)遍歷Generator函數(shù)。
共同特點(diǎn):讓 Generator 函數(shù)恢復(fù)執(zhí)行,并且使用不同的語(yǔ)句替換yield表達(dá)式。
示例
function* f() {
for(var i = 0; true; i++) {
var reset = yield i;
if(reset) { i = -1; }
}
}
var g = f();
g.next() // { value: 0, done: false }
g.next() // { value: 1, done: false }
g.next(true) // { value: 0, done: false }