一日客語:中文:星 客語:sen24 sam三聲
1.生成器:function* name /function *name
2.yield運算子搭配可以暫停
3.next()恢復執行
//宣告function
function* animal() {}
console.log(animal());
//function 表達式
const animalx = function* () {};
console.log(animalx());
//生成器定義在物件內
const myObject = {
*animal() {},
};
console.log(myObject.animal());
//生成器定義在class內
class Zoo {
*animal() {}
}
const myanimal = new Zoo();
console.log(myanimal.animal());
使用yield
生成器就暫停執行,耐心等待另一個請求(next)進來
function* mygen() {
console.log('執行第一句'); //1
yield; //暫停可以使用yield //2
console.log('執行第一句'); //3
}
要如何使用?
function 內使用yield
來暫停
generator object 使用next()繼續
無法透過呼叫mygen使用生成器,要透過迭代器來控制
要呼叫生成器會建立出迭代器, 像是mygen()會回傳 generator object
利用迭代器呼叫生成器來控制process
給外部使用的方法叫next()
,返回值是一個物件{value:xxx,done:true/false}
,向生成器要一個值(value)
done是指生成器的目前狀態,當done是true 時,表示function已經執行完畢,若是false時,表示function尚未執行完畢還可以進行
會一直重跑第一句
function* mygen() {
console.log('執行第一句'); //1
yield; //暫停 //2
console.log('執行第三句'); //3
}
mygen().next(); //執行第一句
mygen().next(); //執行第一句
mygen()到變數a,使用變數a來操控
function* mygen() {
yield;
}
const a = mygen();
a.next();
第一個next(),會開始執行跑每一行直到遇到第一yield,碰到yield會返回value,生成器會一直等到出現第二個next()
來源:A Simple Guide to Understanding Javascript (ES6) Generator
function* mygen() {
console.log('執行第一句'); //1
yield; //暫停 //2
console.log('執行第三句'); //3
}
const a = mygen();
a.next(); //{ value: undefined, done: false }
a.next(); //{ value: undefined, done: true }
第一個:a.next():在生成器內重頭開始
印出執行第一句
遇到yield暫停,返回value
第二個:a.next(),從暫停下一行繼續開始
yield可以透過next丟出一個值
generator object
.next()
會返回一個物件,物件屬性名會有value 和done
function* mygen() {
console.log('執行第一句'); //1
yield '起床'; //暫停 //2
console.log('執行第三句'); //3
yield '刷牙';
}
const a = mygen();
let state1 = a.next(); //執行第一句
console.log(state1); //{ value: '起床', done: false }
let state2 = a.next(); //執行第三句
console.log(state2); //{ value: '刷牙', done: false }
最後一個next 是undefined 因為yield沒有值且沒有return值
function* Pig() {
yield '吃早餐';
yield '睡一下';
yield '吃點心';
yield '睡一下';
}
let pigGen = Pig();
console.log(pigGen.next()); //{ value: '吃早餐', done: false }
console.log(pigGen.next()); //{ value: '睡一下', done: false }
console.log(pigGen.next()); //{ value: '吃點心', done: false }
console.log(pigGen.next()); //{ value: '睡一下', done: false }
console.log(pigGen.next()); //{ value: undefined, done: true }
當function 內有返回值時
可以看到最後一句{ value: '豬', done: true }
的value不是undefined會是return '豬';
function* Pig() {
yield '吃早餐';
yield '睡一下';
yield '吃點心';
yield '睡一下';
return '豬';
}
let pigGen = Pig();
console.log(pigGen.next()); //{ value: '吃早餐', done: false }
console.log(pigGen.next()); //{ value: '睡一下', done: false }
console.log(pigGen.next()); //{ value: '吃點心', done: false }
console.log(pigGen.next()); //{ value: '睡一下', done: false }
console.log(pigGen.next()); //{ value: '豬', done: true }
後面都會被忽略掉,就算後面有yield也會是undefined
function* Pig() {
yield '吃早餐';
return '豬';
yield '睡覺';
}
let pigGen = Pig();
console.log(pigGen.next()); //{ value: '吃早餐', done: false }
console.log(pigGen.next()); //{ value: '豬', done: true }
console.log(pigGen.next()); //{ value: undefined, done: true }
算是運算子一種
yield a + b + c;
因為+優先權高於 yield所以可以不用括號
會自動視為 yield (a + b + c);
但遇到運算子優些權高於yield 就要括號摟,因為yield優先權超低的
console.log('Hello' + yield 123); // SyntaxError
console.log('Hello' + (yield 123)); // OK
使用方式: yield* 生成器
function* Cat() {
yield '喵喵喵';
yield '喵咪睡午覺';
}
function* Pig() {
yield '吃早餐';
yield '睡覺';
yield* Cat();
yield '齁齁齁';
return '結束';
}
let pigGen = Pig();
console.log(pigGen.next());
console.log(pigGen.next());
console.log(pigGen.next());
console.log(pigGen.next());
console.log(pigGen.next());
console.log(pigGen.next());
//{ value: '吃早餐', done: false }
//{ value: '睡覺', done: false }
//{ value: '喵喵喵', done: false }
//{ value: '喵咪睡午覺', done: false }
//{ value: '齁齁齁', done: false }
//{ value: '結束', done: true }
Generator.prototype.next()
語法:next(value)
mdn:
The value to send to the generator.
The value will be assigned as a result of a yield expression. For example, in variable = yield expression, the value passed to the .next() function will be assigned to variable.
next的value值會賦值給 yield expression的結果
next()會回傳一個物件,( )內可以傳參數,傳送到yield 表達式賦予的變數上
將 yield 表達式賦值到一個變數上,使用next(value)語法內的value會傳到這個變數
function* Pig() {
let value1 = yield 100;
console.log(value1);
yield 200;
}
const littlePig = Pig();
console.log(littlePig.next('好吃好吃'));
console.log(littlePig.next('吃24hr'));
console.log(littlePig.next());
//{ value: 100, done: false }
//吃24hr
//{ value: 200, done: false }
//{ value: undefined, done: true }
圖示解說:
所以value1會是'吃24hr'
牛刀小試一下:運用在for-loop
for (let i = 5; i >= 1; i--) {
console.log(i);
}
//5
//4
//3
//2
//1
以下情境只是幻想:
codereview時
饅頭大人chris爆炸前要趕快關懷饅頭大人的胃,
如果使用for迴圈會一直問肚子餓不餓,肯定會更生氣!!
若使用生成器可以隔一段時間再詢問,尤其在血糖急據降低的時侯投食才是恰到好處作法
function* genforloop(n) {
for (let i = 1; i <= 5; i++) {
let dessert = yield `第${i}次問chris肚子餓不餓`;
console.log(`要不要吃${dessert},chris:非常需要`);
}
yield;
return '絕對不生氣,萬歲';
}
let mygen = genforloop(5);
mygen.next();
console.log('code review 15min');
mygen.next('oreo');
console.log('code review 30min');
mygen.next('麥當勞');
console.log('code review 1hr');
mygen.next('炸雞');
console.log('code review 1hr15min');
mygen.next('豆花');
console.log('code review 1hr30min');
mygen.next('紅豆餅');
console.log(mygen.next());
//code review 15min
//要不要吃oreo,chris:非常需要
//code review 30min
//要不要吃麥當勞,chris:非常需要
//code review 1hr
//要不要吃炸雞,chris:非常需要
//code review 1hr15min
//要不要吃豆花,chris:非常需要
//code review 1hr30min
//要不要吃紅豆餅,chris:非常需要
//{ value:'絕對不生氣,萬歲', done: true }
感謝饅頭大人當我文章主角
也推薦安迪大大的寫的,如何讓工具人帥一波
傳送門:
方函式的能力展現:認識生成器,工具人更神氣(上)
方函式的能力展現:認識生成器,工具人更神氣(下)
剩下四天了~真是太累了~
參考資料:
Exploring ES6
[譯]什麼是JavaScript生成器?如何使用生成器?
generator的next传参注意点
忍者開發技巧探秘第二版