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ù)設(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)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市随闪,隨后出現(xiàn)的幾起案子阳似,更是在濱河造成了極大的恐慌,老刑警劉巖铐伴,帶你破解...
    沈念sama閱讀 218,858評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件撮奏,死亡現(xiàn)場離奇詭異,居然都是意外死亡当宴,警方通過查閱死者的電腦和手機畜吊,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,372評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來户矢,“玉大人玲献,你說我怎么就攤上這事√堇耍” “怎么了捌年?”我有些...
    開封第一講書人閱讀 165,282評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長挂洛。 經(jīng)常有香客問我礼预,道長,這世上最難降的妖魔是什么虏劲? 我笑而不...
    開封第一講書人閱讀 58,842評論 1 295
  • 正文 為了忘掉前任托酸,我火速辦了婚禮褒颈,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘励堡。我一直安慰自己谷丸,他們只是感情好,可當我...
    茶點故事閱讀 67,857評論 6 392
  • 文/花漫 我一把揭開白布念秧。 她就那樣靜靜地躺著淤井,像睡著了一般布疼。 火紅的嫁衣襯著肌膚如雪摊趾。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,679評論 1 305
  • 那天游两,我揣著相機與錄音砾层,去河邊找鬼。 笑死贱案,一個胖子當著我的面吹牛肛炮,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播宝踪,決...
    沈念sama閱讀 40,406評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼侨糟,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了瘩燥?” 一聲冷哼從身側(cè)響起秕重,我...
    開封第一講書人閱讀 39,311評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎厉膀,沒想到半個月后溶耘,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,767評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡服鹅,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年凳兵,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片企软。...
    茶點故事閱讀 40,090評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡庐扫,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出仗哨,到底是詐尸還是另有隱情形庭,我是刑警寧澤,帶...
    沈念sama閱讀 35,785評論 5 346
  • 正文 年R本政府宣布藻治,位于F島的核電站碘勉,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏桩卵。R本人自食惡果不足惜验靡,卻給世界環(huán)境...
    茶點故事閱讀 41,420評論 3 331
  • 文/蒙蒙 一倍宾、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧胜嗓,春花似錦高职、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,988評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至变过,卻和暖如春埃元,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背媚狰。 一陣腳步聲響...
    開封第一講書人閱讀 33,101評論 1 271
  • 我被黑心中介騙來泰國打工岛杀, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人崭孤。 一個月前我還...
    沈念sama閱讀 48,298評論 3 372
  • 正文 我出身青樓类嗤,卻偏偏與公主長得像,于是被迫代替她去往敵國和親辨宠。 傳聞我的和親對象是個殘疾皇子遗锣,可洞房花燭夜當晚...
    茶點故事閱讀 45,033評論 2 355

推薦閱讀更多精彩內(nèi)容

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