https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Statements/function*
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/yield
生成器函數在執行時能暫停,后面又能從暫停處繼續執行。
調用一個生成器函數並不會馬上執行它里面的語句,而是返回一個這個生成器的 迭代器 (iterator)對象。當這個迭代器的 next() 方法被首次(后續)調用時,其內的語句會執行到第一個(后續)出現 yield 的位置為止,yield 后緊跟迭代器要返回的值。或者如果用的是 yield*(多了個星號),則表示將執行權移交給另一個生成器函數(當前生成器暫停執行)。
next() 方法返回一個對象,這個對象包含兩個屬性:value 和 done,value 屬性表示本次 yield 表達式的返回值,done 屬性為布爾類型,表示生成器后續是否還有 yield 語句,即生成器函數是否已經執行完畢並返回。
調用 next() 方法時,如果傳入了參數,那么這個參數會作為上一條執行的 yield 語句的返回值
當在生成器函數中顯式 return 時,會導致生成器立即變為完成狀態,即調用 next() 方法返回的對象的 done 為 true。如果 return 后面跟了一個值,那么這個值會作為當前調用 next() 方法返回的 value 值。
// 生成器函數定義
function* countAppleSales () {
var saleList = [3, 7, 5];
for (var i = 0; i < saleList.length; i++) {
yield saleList[i];
}
}
// 通過構造一個迭代器來使用它。
var appleStore = countAppleSales(); // Generator { }
console.log(appleStore.next()); // { value: 3, done: false }
console.log(appleStore.next()); // { value: 7, done: false }
console.log(appleStore.next()); // { value: 5, done: false }
console.log(appleStore.next()); // { value: undefined, done: true }
// next方法傳入參數
function *gen(){
y = yield 'foo';
yield y;
}
var gen_obj=gen();
console.log(gen_obj.next());// 執行 yield 'foo',返回 'foo'
console.log(gen_obj.next(10));// 將 10 賦給上一條 yield 'foo' 的左值,即執行 y=10,返回 10
console.log(gen_obj.next());// 執行完畢,value 為 undefined,done 為 true
結合性和優先級
右結合,且優先級極低, 參見:運算符優先級 - JavaScript | MDN,例:
function *a(){
yield yield 1, yield 3;
}
var foo = a();
console.log(foo.next(), foo.next(2), foo.next(), foo.next())// 1 2 3 undefined