1. 程式人生 > 實用技巧 >第7章

第7章

generator生成器函式

定義:

  • function後面加了*
  • 函式體裡有 yield關鍵字
1 2 3 4 5 function* Hello(name) { yield `hello${name}`; yield `how are you`; yield `bye`; }

  

表現形式

  • 呼叫這個函式,不會立即執行函式體裡的內容,返回一個物件
  • 通過這個物件的next方法,可以驅動函式的執行,但是並不會執行完,執行到下一個yield關鍵字的時候,停住
  • 呼叫next()方法返回的結果
    • value: yield關鍵字後面的表示式的結果。
    • done:函式是否執行完。 (當函式return的時候執行完,返回true)
    • 函式return的時候,value是return的內容,done是true
1 2 3 4 5 6 7 8 9 let ite = Hello('前端君'); console.log(ite)//[object Hello] console.log(ite.next());//{value: "hello前端軍",done: false} console.log(ite.next());//{value: "how are you",done: false} console.log(ite.next()); console.log(ite.next());//{value: undefined,done: true}

  

  • next()方法可以加引數
    • next(引數)
    • 這個引數會作為上一個yield關鍵字的返回值

作用

  • 函式可以返回多個值
  • 在呼叫函式之後,可以給函式體裡傳遞資料了
  • 呼叫函式的時候,可以控制函式內部的執行了
  • 可以解決非同步問題

生成器函式的執行器

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 // 寫一個generator函式的執行器 function run(gen) { // 編寫一段遞迴呼叫來執行我們的程式碼 let lt = gen;//這裡呼叫,上面let就不要呼叫
// debugger return new Promise((reslove, reject) => { // {value,done} function step(data) { if (data.done) { console.log("遞迴呼叫結束了"); reslove(data.value) } else { data.value.then(res => { console.log(res); step(lt.next(res)) }) } } step(lt.next()) }) } run(gen);

關鍵字‘yield*’;

作用:一個Generator函式裡面呼叫另一個Generator函式使用yield*

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 function* gen2(){ yield "gen2 start"; yield "gen2 end"; } function* start(){ yield "start"; yield* gen2(); yield "end"; } var ite1 = start(); console.log(ite1.next());//start console.log(ite1.next());//gen2 start console.log(ite1.next());//gen2 end//執行函式時依次執行完 console.log(ite1.next());//end console.log(ite1.next());//undefined

  

與普通函式的區別:

  1. 普通函式用function來宣告,Generator函式用function*宣告。

  2.Generator函式函式內部有新的關鍵字:yield(產出),普通函式沒有.

return與yield的區別:

yield在這裡起到了十分重要的作用,就相當於暫停執行並且返回資訊。 return代表的是終止執行,yield代表的是暫停執行