generator(生成器)小結(jié)

初遇

生成器函數(shù),顧名思義,生成對象,生成一個遍歷器。

function* generator(){
    yield 0;
    yield 1;
    yield 2;
}

let iterator = generator();

iterator.next();    //{value:0,done:false}
iterator.next();    //{value:1,done:false}
iterator.next();    //{value:2,done:false}
iterator.next();    //{value:undefined,done:true}
  • generator()為生成器函數(shù),在function函數(shù)名之間添加*表明該函數(shù)為生成器函數(shù)。
  • generaotor()調(diào)用返回一個遍歷器,賦值給iterator。
  • iterator有多個方法,next()、return()throw()。
  • 通過yield和上述三個方法控制生成器函數(shù)代碼塊的執(zhí)行。

yield和next( )

  • 生成器代碼不會自動執(zhí)行,多個yield將代碼分成多個部分,等待信號才會執(zhí)行,信號就是上述遍歷器的幾個方法。
  • 調(diào)用next()時生成器代碼執(zhí)行,執(zhí)行完含yield語句時停止。下一次調(diào)用next()時,繼續(xù)執(zhí)行。
  • next()的返回值為一個對象:{value:"",done:false},該對象包含value、done字段。
  • value值為本次執(zhí)行代碼中yield其后表達式的值。done的值為true或者false,表示當前遍歷器是否執(zhí)行完畢。
  • 上述代碼執(zhí)行情況
    1.第一個next()啟動生成器執(zhí)行,執(zhí)行完yield 0后停止,next()返回值為{value:0,done:false}。
    2.第二個next()調(diào)用,生成器繼續(xù)執(zhí)行,執(zhí)行完yield 1后停止,next()返回值為{value:1,done:false}。
    3.第三次next()調(diào)用和第二次相似,next()返回值為{value:2,done:false}
    4.第四次next()調(diào)用時,生成器已執(zhí)行完畢,value字段值默認值undefined,done字段值為true。后續(xù)調(diào)用都是如此。

    yield語句返回值、next( )參數(shù)

    • yield語句默認為值為undefined。
    function* generator () {
          const data0 = yield 0;
          console.log(data0);         //打印出值為undefined
    
          const data1 = yield 1;     
          console.log(data1);         //打印出值為undefined
    
          const data2 = yield 2;     
          console.log(data2);         //打印出值為undefined
      }
    
      let iterator = generator();
    
      iterator.next();
      iterator.next();
      iterator.next();
      iterator.next();
      //yield語句默認值為undefined,data0、data1、data2所賦到的值為undefined
    
    • 通過向next()傳入?yún)?shù)改變上個yield語句的返回值。
      function* generator () {
          const data0 = yield 1;
          console.log(data0);         //打印出值為"data0"
    
          const data1 = yield 1;     
          console.log(data1);         //打印出值為"data1"
    
          const data2 = yield 2;     
          console.log(data2);         //打印出值為"data2"
      }
    
      let iterator = generator();
    
      iterator.next();
      iterator.next("data0");
      iterator.next("data1");
      iterator.next("data2");
    

return( )

這樣一段代碼,生成器中含return語句。遍歷器剛好結(jié)束遍歷時,value字段默認值為undefined,return返回的值會賦給當前next()返回值的value字段。即代碼塊中第三次next()調(diào)用。

  function* generator(){
      yield 0;
      yield 1;
      return 2;
  }
  
  let iterator = generator();
  
  console.log(iterator.next());    //{value:0,done:false}
  console.log(iterator.next());    //{value:1,done:false}
  console.log(iterator.next());    //{value:2,done:true}
  console.log(iterator.next());    //{value:undefined,done:true}

遍歷器的return()

遍歷器的next()表示繼續(xù)向后執(zhí)行,return則表示直接返回,結(jié)束執(zhí)行。

  function* generator() {
      yield 0;
      yield 1;
      yield 2;
  }

  let iterator = generator();
  console.log(iterator.next());
  console.log(iterator.return());
  • 上述代碼執(zhí)行完yield 0后停止,return()被調(diào)用,提前結(jié)束遍歷。后續(xù)yield 1、yield 2不會被執(zhí)行。
  • return()返回值默認為{value:undefined,done:true}。value字段值可由return()的參數(shù)設置,同next()。

throw( )

  • 所生成遍歷器也有自己的throw(),會優(yōu)先觸發(fā)生成器內(nèi)部的try-catch。
function* generator() {
       try {
           const data = yield;
       } catch(e) {
           console.log("內(nèi)部檢測到",e.message);
       }
   }
   let iterator = generator();
   iterator.next();
   iterator.throw(new Error("error"))
  • 內(nèi)部無try-catch時,觸發(fā)外部try-catch。
  • 多次 throw()時,第一次由內(nèi)部捕獲,后續(xù)由外部捕獲。

底層原理

  • 基于協(xié)程的實現(xiàn)。
  • 單個線程上可有多個協(xié)程,線程控制權(quán)可交由不同的協(xié)程控制,每個時間點只能由一個協(xié)程控制。
  • 運行生成器函數(shù)時創(chuàng)建新的協(xié)程,所創(chuàng)建它的協(xié)程的稱為父協(xié)程。
  • 開始時由父協(xié)程控制,調(diào)用next()時,將線程控制權(quán)交由生成器協(xié)程,遇到yeild時將控制權(quán)交回父協(xié)程。
  • 每個協(xié)程在轉(zhuǎn)交控制權(quán)前都會保存自己的調(diào)用棧,方便再次執(zhí)行。
    本文只是浮光掠影,更多細節(jié)內(nèi)容請前往阮一峰ES6
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

  • Generator 函數(shù)的語法 簡介 基本概念 Generator 函數(shù)是 ES6 提供的一種異步編程解決方案,語...
    站在大神的肩膀上看世界閱讀 4,315評論 0 6
  • 簡介 基本概念 Generator函數(shù)是ES6提供的一種異步編程解決方案,語法行為與傳統(tǒng)函數(shù)完全不同。本章詳細介紹...
    呼呼哥閱讀 1,136評論 0 4
  • 在此處先列下本篇文章的主要內(nèi)容 簡介 next方法的參數(shù) for...of循環(huán) Generator.prototy...
    醉生夢死閱讀 1,488評論 3 8
  • 一、簡介 1.1、基本概念 Generator 函數(shù)時 ES6 提供的一種異步編程解決方案。從語法上看,可以把它理...
    了凡和纖風閱讀 205評論 0 1
  • 窗里月光窗外滿,弄影今宵,自有清風伴。相勸豈能杯酒淺,任憑一醉愁眉展。 曾幾落花春不管,遍地殘紅,留與誰驚看?以往...
    雪窗_武立之閱讀 512評論 4 8

友情鏈接更多精彩內(nèi)容