0.背景
今天要討論的Generators,在上一篇中提到過,這一篇稍微談談。
1.概覽
生成器的寫法
var fibonacci = {
[Symbol.iterator]: function*() {
var pre = 0, cur = 1;
for (;;) {
var temp = pre;
pre = cur;
cur += temp;
yield cur;
}
}
}
for (var n of fibonacci) {
// truncate the sequence at 1000
if (n > 1000)
break;
console.log(n);
}
2.展開聊聊
2.1.Generator.prototype.next()
next()
方法返回一個包含屬性 done
和 value
的對象。該方法也可以通過接受一個參數用以向生成器傳值。
舉個例子:
function* gen() {
yield 1;
yield 2;
yield 3;
}
var g = gen(); // "Generator { }"
g.next(); // "Object { value: 1, done: false }"
g.next(); // "Object { value: 2, done: false }"
g.next(); // "Object { value: 3, done: false }"
g.next(); // "Object { value: undefined, done: true }"
一般情況下,next 方法不傳入參數的時候,yield 表達式的返回值是 undefined 。當 next 傳入參數的時候,該參數會作爲上一步yield的返回值。
function* sendParameter(){
console.log("start");
var x = yield '2';
console.log("one:" + x);
var y = yield '3';
console.log("two:" + y);
console.log("total:" + (x + y));
}
var sendp1 = sendParameter();
sendp1.next();
// start
// {value: "2", done: false}
sendp1.next();
// one:undefined
// {value: "3", done: false}
sendp1.next();
// two:undefined
// total:NaN
// {value: undefined, done: true}
// ----------------------------------------------------next傳參
var sendp2 = sendParameter();
sendp2.next(10);
// start
// {value: "2", done: false}
sendp2.next(20);
// one:20
// {value: "3", done: false}
sendp2.next(30);
// two:30
// total:50
// {value: undefined, done: true}
2.2.Generator.prototype.return()
return()
方法返回給定的值並結束生成器。
function* gen() {
yield 1;
yield 2;
yield 3;
}
var g = gen();
g.next(); // { value: 1, done: false }
g.return("foo"); // { value: "foo", done: true }
g.next(); // { value: undefined, done: true }
2.3.Generator.prototype.throw()
throw() 方法用來向生成器拋出異常,並恢復生成器的執行,返回帶有 done 及 value 兩個屬性的對象。
function* gen() {
while(true) {
try {
yield 42;
} catch(e) {
console.log("Error caught!");
}
}
}
var g = gen();
g.next(); // { value: 42, done: false }
g.throw(new Error("Something went wrong")); // "Error caught!"
3.結語
生成器這部分,個人還是覺得多看多聽多學,遇到確實好的實踐再用,瞎用只會增加閱讀代碼的負擔。