Generator筆記

1 Generator 函數是一個狀態機,封裝了多個內部狀態

2 執行 Generator 函數會返回一個遍歷器對象;返回的遍歷器對象,可以依次遍歷 Generator 函數內部的每一個狀態

3 特徵

  • function關鍵字與函數名之間有一個星號
  • 函數體內部使用 yield 表達式,定義不同的內部狀態(yield在英語裏的意思就是“產出”)

4 調用 Generator 函數後,該函數並不執行,返回的也不是函數運行結果,而是一個指向內部狀態的指針對象,即遍歷器對象(Iterator Object)

5 每次調用next方法,內部指針就從函 數頭部或上一次停下來的地方開始執行,直到遇到下一個yield表達式(或return語句)爲止

6 Generator 函數是分段執行的,yield表達式是暫停執行的標記,而next方法可以恢復執行

7 每次調用遍歷器對象的next方法,就會返回一個有着value和done兩個屬性的對象。value屬性表示當前的內部狀態的值,是yield表達式後面那個表達式的值;done屬性是一個布爾值,表示是否遍歷結束

8 yield表達式如果用在另一個表達式之中,必須放在圓括號裏面

9 yield表達式用作函數參數或放在賦值表達式的右邊,可以不加括號

10 由於 Generator 函數就是遍歷器生成函數,因此可以把 Generator 賦值給對象的Symbol.iterator屬性,從而使得該對象具有 Iterator 接口

11 Generator 函數執行後,返回一個遍歷器對象。該對象本身也具有Symbol.iterator屬性,執行後返回自身。

function* gen(){
  // some code
}

var g = gen();

g[Symbol.iterator]() === g
// true

12 遍歷器對象的next方法的運行邏輯:

(1)遇到yield表達式,就暫停執行後面的操作,並將緊跟在yield後面的那個表達式的值,作爲返回的對象的value屬性值

(2)下一次調用next方法時,再繼續往下執行,直到遇到下一個yield表達式。

(3)如果沒有再遇到新的yield表達式,就一直運行到函數結束,直到return語句爲止,並將return語句後面的表達式的值,作爲返回的對象的value屬性值。

(4)如果該函數沒有return語句,則返回的對象的value屬性值爲undefined。

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

function* f() {
  for(var i = 0; true; i++) {
    console.log('i', i);
    var reset = yield i;
    console.log('reset',reset);
    if(reset) { i = -1; }
    console.warn('i', i);
  }
}

var g = f();

console.log(g.next()) // { value: 0, done: false }
console.log(g.next()) // { value: 1, done: false }
console.log(g.next(true)) // { value: 0, done: false }

// 執行第一個next
// i 0
// {value: 0, done: false}  // 遇到yield,暫停後面的操作,緊跟在yield後面的那個表達式的值0,作爲返回的對象的value屬性值
// 執行第二個next,沒有傳入參數,reset爲undefined
// reset undefined
// i 0
// i 1
// {value: 1, done: false}
// 執行第三個next,傳入參數true,reset爲true
// reset true
// i -1
// i 0
// {value: 0, done: false}

14  由於next方法的參數表示上一個yield表達式的返回值,所以在第一次使用next方法時,傳遞參數是無效的。V8 引擎直接忽略第一次使用next方法時的參數,只有從第二次使用next方法開始,參數纔是有效的。從語義上講,第一個next方法用來啓動遍歷器對象,所以不用帶有參數。

15  一旦next方法的返回對象的done屬性爲truefor...of循環就會中止,且不包含該返回對象,

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章