Generator

基本概念

  1. Generator 函數是一個狀態機,封裝了多個內部狀態。
  2. 函數體內部使用yield表達式,定義不一樣的內部狀態。
  3. 執行 Generator 函數會返回一個遍歷器對象,必須調用遍歷器對象的next方法,使得指針移向下一個狀態。
  4. next方法返回一個對象,它的value屬性就是當前 yield表達式的值,done屬性是布爾值,false表示遍歷尚未結束,true 表示便利結束。如:
function* helloWorldGenerator() { yield 'hello'; yield 'world'; return 'ending'; } var hw = helloWorldGenerator(); hw.next() // { value: 'hello', done: false } function* helloWorldGenerator() { yield 'hello'; yield 'world'; return 'ending'; } var hw = helloWorldGenerator(); hw.next() // { value: 'hello', done: false }

yield 表達式 & next()

  1. Generator 函數是分段執行的,yield表達式是暫停執行的標記,而next方法能夠恢復執行。
  2. yield表達式自己沒有返回值,或者說老是返回undefined
  3. next方法能夠帶一個參數,該參數就會被看成上一個yield表達式的返回值
  4. 經過next方法的參數,就有辦法在 Generator 函數開始運行以後,繼續向函數體內部注入值。也就是說,能夠在 Generator 函數運行的不一樣階段,從外部向內部注入不一樣的值,從而調整函數行爲

for...of 循環

  1. for...of循環能夠自動遍歷 Generator 函數運行時生成的Iterator對象,且此時再也不須要調用next方法
  2. 一旦next方法的返回對象的done屬性爲true,for...of循環就會停止,且不包含該返回對象,因此上面代碼的return語句返回的6,不包括在for...of循環之中
  3. 使用for...of就不用調用next()方法了,可是這裏for...of 拿到的值就是next()方法返回的value值.
function* iterEntries(obj) { let keys = Object.keys(obj); for (let i=0; i < keys.length; i++) { let key = keys[i]; yield [key, obj[key]]; } } let myObj = { foo: 3, bar: 7 }; // for...of 拿到的值就是yield表達式的值,因此才能結構。 for (let [key, value] of iterEntries(myObj)) { console.log(key, value); } // foo 3 // bar 7 function* iterEntries(obj) { let keys = Object.keys(obj); for (let i=0; i < keys.length; i++) { let key = keys[i]; yield [key, obj[key]]; } } let myObj = { foo: 3, bar: 7 }; // for...of 拿到的值就是yield表達式的值,因此才能結構。 for (let [key, value] of iterEntries(myObj)) { console.log(key, value); } // foo 3 // bar 7

Generator的異步應用

 function showLoadingScreen() { console.log('step1'); } function loadUIDataAsynchronously() { setTimeout(() => { loader.next("異步操做sync"); // 把結果傳遞出去 }, 2000); } function hideLoadingScreen() { console.log('step3'); } function* loadUI() { showLoadingScreen(); var res = yield loadUIDataAsynchronously(); console.log(res) //拿到異步執行的結果 hideLoadingScreen(); } var loader = loadUI(); loader.next() function showLoadingScreen() { console.log('step1'); } function loadUIDataAsynchronously() { setTimeout(() => { loader.next("異步操做sync"); // 把結果傳遞出去 }, 2000); } function hideLoadingScreen() { console.log('step3'); } function* loadUI() { showLoadingScreen(); var res = yield loadUIDataAsynchronously(); console.log(res) //拿到異步執行的結果 hideLoadingScreen(); } var loader = loadUI(); loader.next()

Generator 函數的this

  1. Generator 函數老是返回一個遍歷器,而不是this對象,ES6 規定這個遍歷器是 Generator 函數的實例,也繼承了 Generator 函數的prototype對象上的方法。
  2. 獲取正常this方式:
 function* F() { yield this.name = 'generator' } F.prototype.getName = function() { console.log(this.name) //undefind 這裏拿不到定義的狀態 console.log(this) // F {<suspended>} console.log('gen') // 'gen' }; // 聲明一個空的對象 var obj = {}; var f = F.call(obj); f.next() f instanceof F; // true f.getName(); //標註在實例方法中 console.log(obj.name) //這裏也是隻用執行了next()方法後才能打印出 generator' ,不然就是undefined function* F() { yield this.name = 'generator' } F.prototype.getName = function() { console.log(this.name) //undefind 這裏拿不到定義的狀態 console.log(this) // F {<suspended>} console.log('gen') // 'gen' }; // 聲明一個空的對象 var obj = {}; var f = F.call(obj); f.next() f instanceof F; // true f.getName(); //標註在實例方法中 console.log(obj.name) //這裏也是隻用執行了next()方法後才能打印出 generator' ,不然就是undefined

es6

摘自阮一峯es6 function* F() { yield this.name = 'generator' } F.prototype.getName = function() { console.log(this.name) //undefind 這裏拿不到定義的狀態 console.log(this) // F {<suspended>} console.log('gen') // 'gen' }; // F本身原型 var f = F.call(F.prototype); f.next() f instanceof F; // true f.getName(); //標註在實例方法中 console.log(f.name) //這裏也是隻用執行了next()方法後才能打印出 generator' ,不然就是undefinedfunction* F() { yield this.name = 'generator' } F.prototype.getName = function() { console.log(this.name) //undefind 這裏拿不到定義的狀態 console.log(this) // F {<suspended>} console.log('gen') // 'gen' }; // F本身原型 var f = F.call(F.prototype); f.next() f instanceof F; // true f.getName(); //標註在實例方法中 console.log(f.name) //這裏也是隻用執行了next()方法後才能打印出 generator' ,不然就是undefined
相關文章
相關標籤/搜索