generator 生成器javascript
yield 能夠使生成器返回屢次
我習慣於從表象推測,不喜歡官方文檔,寫的字都認識,結果變成句子以後,就一句都看不懂java
如今要生成自增的id函數
傳統寫法spa
var public_id = 0; function idUp () { public_id++; } idUp() // 須要新id時,調用 idUp ,使外部的變量+1 ,無論是使用變量,仍是把id當作參數傳入函數,函數內部沒法保存id的當前狀態(意思就是,若是沒有外部變量也沒有傳參,函數就不知道id如今是多少).
使用生成器code
function* idUp () { let id = 0; while (true) { yield id id++; } } var addId = idUp(); var newId = addId.next().value; // 須要新id時,使用 addId.next().value, 咱們無需關心外部是否有id,由於id的狀態在函數裏面
注意兩種方式的不一樣之處。對象
傳統寫法須要一個全局變量來保存id的狀態,而使用 生成器 狀態保存在生成器中(就這樣理解吧,使用生成器的時候,就不須要定義全局變量了存儲id了)。blog
你們也許會有疑問,使用 while(true) 都死循環了,這個 生成器真的能用麼? 實則yield 會使 生成器暫停,一直到調用next()纔會繼續執行函數,直到遇到下一個yield或者returnip
寫個簡單的 生成器的例子來看一下文檔
function *example () { let a = 0; console.log('第一次輸出時a的值', a); yield a; a++; console.log('第二次輸出時a的值', a); yield a; a++; console.log('第三次輸出時a的值', a); return a; } var doExample = example(); // 此時並不會輸出 , 我的理解是, 生成器在當作函數執行的時候,實際上是返回了一個 生成器對象,或者說盒子比較恰當,生成器裏面的真正須要執行的代碼被放到了這個盒子裏面。 console.log(doExample); // 輸出 example {<suspended>} console.log(doExample.next()); // 輸出 「第一次輸出時a的值 0 」 和 {value: 0, done: false} console.log(doExample.next()); // 輸出 「第二次輸出時a的值 1 」 和 {value: 1, done: false} console.log(doExample.next()); // 輸出 「第三次輸出時a的值 2 」 和 {value: 2, done: true} console.log(doExample.next()); // 輸出 {value: undefined, done: true}
以上代碼主要就是看一下 生成器的執行流程,主要是 經過這段代碼來理解這樣兩個概念generator
1.yield 能夠暫停生成器
2.next 繼續執行生成器直到 遇到下一個yield或者return
如今能夠理解上面使用whil(true)了,可是並不會致使死循環,由於程序的執行實際上是控制在 生成器的next手裏。
另一個須要 特別說一下的知識點是 每次執行next返回的對象裏面 的 done 表明了生成器是否執行完成。能夠理解爲後面是否還有yield 若是還有yield,則 done:false 若是沒有yield了,則爲 true
而且,當生成器執行到末尾的時候,既 done:true 的時候,再次執行 next ,並無任何輸出,且 value 變成了 undefined。這裏爲啥是 undefined 。再寫一個例子。
function *test () { let a = 0; yield; a++; yield a; a++; return a; } var doTest = test(); console.log(doTest.next()); // 輸出 {value: undefined, done: false} console.log(doTest.next()); // 輸出 {value: 1, done: false} console.log(doTest.next()); // 輸出 {value: 2, done: true}
console.log(doTest.next());
// 輸出 {value: undefined, done: true}
比較和上一個例子的區別,第一次輸出的 value 的值是 undefined ,由於代碼中 yield 後面什麼都沒有。第二次value的值是1,由於代碼中yield後面接了 a。 意思就是value裏面的值是 yield 後面的東西。
因此,最後輸出 undefined 是否是就理解了 (由於代碼都跑完了,已經沒有yield了,天然就不會再有值了,value天然就是空)
好了就說這麼多了,還有更多坑,你們有興趣的能夠本身去踩踩。
。。。。