JavaScript的Generator理解使用

2021-09-14 07:56:58 字數 2798 閱讀 7326

generator 函式是 es6 提供的一種非同步程式設計解決方案,可以這麼理解:

從語法上,首先可以把它理解成,generator 函式是乙個狀態機,封裝了多個內部狀態。

執行 generator 函式會返回乙個遍歷器物件,也就是說,generator 函式除了狀態機,還是乙個遍歷器物件生成函式。返回的遍歷器物件,可以依次遍歷 generator 函式內部的每乙個狀態。

形式上,generator 函式是乙個普通函式,但是有兩個特徵。一是,function關鍵字與函式名之間有乙個星號;二是,函式體內部使用yield表示式,定義不同的內部狀態(yield在英語裡的意思就是「產出」)。

function* helloworldgenerator() 

var hw = helloworldgenerator();

generator 函式的呼叫方法與普通函式一樣,也是在函式名後面加上一對圓括號。不同的是,呼叫 generator 函式後,該函式並不執行,返回的也不是函式執行結果,而是乙個指向內部狀態的指標物件,也就是上一章介紹的遍歷器物件(iterator object)。

下一步,必須呼叫遍歷器物件的next方法,使得指標移向下乙個狀態。也就是說,每次呼叫next方法,內部指標就從函式頭部或上一次停下來的地方開始執行,直到遇到下乙個yield表示式(或return語句)為止。換言之,generator 函式是分段執行的,yield表示式是暫停執行的標記,而next方法可以恢復執行。

hw.next()

// hw.next()

// hw.next()

// hw.next()

//

上面的程式執行了四次next:

第一次呼叫,generator 函式開始執行,直到遇到第乙個yield表示式為止。next方法返回乙個物件,它的value屬性就是當前yield表示式的值hello,done屬性的值false,表示遍歷還沒有結束。

第二次呼叫,generator 函式從上次yield表示式停下的地方,一直執行到下乙個yield表示式。next方法返回的物件的value屬性就是當前yield表示式的值world,done屬性的值false,表示遍歷還沒有結束。

第三次呼叫,generator 函式從上次yield表示式停下的地方,一直執行到return語句(如果沒有return語句,就執行到函式結束)。next方法返回的物件的value屬性,就是緊跟在return語句後面的表示式的值(如果沒有return語句,則value屬性的值為undefined),done屬性的值true,表示遍歷已經結束。

第四次呼叫,此時 generator 函式已經執行完畢,next方法返回物件的value屬性為undefined,done屬性為true。以後再呼叫next方法,返回的都是這個值。

由於 generator 函式返回的遍歷器物件,只有呼叫next方法才會遍歷下乙個內部狀態,所以其實提供了一種可以暫停執行的函式。yield表示式就是暫停標誌。

(1)遇到yield表示式,就暫停執行後面的操作,並將緊跟在yield後面的那個表示式的值,作為返回的物件的value屬性值。

(2)下一次呼叫next方法時,再繼續往下執行,直到遇到下乙個yield表示式。

(3)如果沒有再遇到新的yield表示式,就一直執行到函式結束,直到return語句為止,並將return語句後面的表示式的值,作為返回的物件的value屬性值。

(4)如果該函式沒有return語句或者執行完return之後再執行next的時候,則返回的物件的value屬性值為undefined,done為true。

需要注意,yield表示式只能用在 generator 函式裡面,用在其他地方都會報錯。

yield表示式如果用在另乙個表示式之中,必須放在圓括號裡面

yield表示式用作函式引數或放在賦值表示式的右邊,可以不加括號。

yield放在表示式中的時候,let s =(yield 1+2),s其值將會是undefined,而1+2這個等於3的值將會作為next返回物件的value的值

yield表示式本身沒有返回值,或者說總是返回undefined。next方法可以帶乙個引數,該引數就會被當作上乙個yield表示式的返回值。

這個引數就是解決了上面說的注意事項的最後乙個,yield的返回值總是undefined,

由於next方法的引數表示上乙個yield表示式的返回值,所以在第一次使用next方法時,傳遞引數是無效的。v8 引擎直接忽略第一次使用next方法時的引數,只有從第二次使用next方法開始,引數才是有效的。從語義上講,第乙個next方法用來啟動遍歷器物件,所以不用帶有引數。

如果在 generator 函式內部,呼叫另乙個 generator 函式,預設情況下是沒有效果的。

這個就需要用到yield*表示式,用來在乙個 generator 函式裡面執行另乙個 generator 函式。

function* inner() 

function* outer1()

var gen = outer1()

gen.next().value // "open"

gen.next().value // 返回乙個遍歷器物件

gen.next().value // "close"

function* outer2()

var gen = outer2()

gen.next().value // "open"

gen.next().value // "hello!"

gen.next().value // "close"

gene6的幾個使用技巧

1 通過類使用者實現帳戶統一管理 在gene6中為我們提供了類的概念,通過新建類可以統一管理帳戶,讓不同帳戶享受同樣的管理和許可權,他還是有別於我們常說的使用者組的。類使用者 可以各自不同也可以各自相同,而使用者組往往相同點過於多。新建類操作可以直接在 使用者 管理介面通過右鍵選擇完成。4 訪問限制...

javascript的時間函式

var mydate new date mydate.getyear 獲取當前年份 2位 mydate.getfullyear 獲取完整的年份 4位,1970 mydate.getmonth 獲取當前月份 0 11,0代表1月 mydate.getdate 獲取當前日 1 31 mydate.get...

javascript物件的建立

function createoject name,return object var aa createoject zhangsan nan aa.run 利用第一種方式的問題就是不能識別他是什麼物件 function myobject name,var testobect new myobjec...