學習ECMAScript 2015【9】Generators

0.背景

今天要討論的Generators,在上一篇中提到過,這一篇稍微談談。

image.png

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() 方法返回一個包含屬性 donevalue 的對象。該方法也可以通過接受一個參數用以向生成器傳值。

舉個例子:

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.結語

生成器這部分,個人還是覺得多看多聽多學,遇到確實好的實踐再用,瞎用只會增加閱讀代碼的負擔。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章