Generator
Generator函數是ES6提供的一種異步編程解決方案,Generator函數是一個狀態機,封裝了多個內部狀態。
執行Generator函數會返回一個遍歷器對象,也就是說,Generator函數除了狀態機,還是一個遍歷器對象生成函數。返回的遍歷器對象,可以依次遍歷Generator函數內部的每一個狀態。
Generator的兩個特征:
function
關鍵字與函數名之間有一個星號- 函數體內部使用
yield(產出)
語句,定義不同的內部狀態
function* helloWorldGenerator() {yield 'hello';yield 'world';return 'ending'; }var hw = helloWorldGenerator();
hw.next() // { value: 'hello', done: false } hw.next() // { value: 'world', done: false } hw.next() // { value: 'ending', done: true } hw.next() // { value: undefined, done: true }
yield語句
由于Generator函數返回的遍歷器對象,只有調用next
方法才會遍歷下一個內部狀態,所以其實提供了一種可以暫停執行的函數。yield
語句就是暫停標志。
yield和return
相似:都能返回緊跟在語句后面的那個表達式的值
區別:
- 每次遇到
yield
,函數暫停執行,下一次再從該位置繼續向后執行,而return
語句不具備位置記憶的功能 - 一個函數里面,只能執行一次(或者說一個)
return
語句,但是可以執行多次(或者說多個)yield
語句。
在使用for...of時自動遍歷Generator函數,不需要調用next方法
yield*語句
如果在Generater函數內部,調用另一個Generator函數,默認情況下是沒有效果的。這個就需要用到yield*
語句,用來在一個Generator函數里面執行另一個Generator函數。
function* bar() {yield 'x';yield* foo();yield 'y'; }// 等同于 function* bar() {yield 'x';yield 'a';yield 'b';yield 'y'; }// 等同于 function* bar() {yield 'x';for (let v of foo()) {yield v;}yield 'y'; }for (let v of bar()){console.log(v); } // "x" // "a" // "b" // "y"
?