速習ECMAScript2018を勉強する ジェネレータ編

ジュネレータ

  • 列挙可能なオブジェクトをより簡単に記述できる記法とのこと

function* myGenerator() {
    yield 'A';
    yield 'B';
    yield 'C';
}

for(let value of myGenerator()) {
    console.log(value)
}
  • 書き方が独特ですね、アスタリスクが付いて、return の代わりにyield が使われています.

  • while文にいれてみて、同じかどうか検証してみます。

function* myGenerator() {
    yield 'A';
    yield 'B';
    yield 'C';
}

console.log(myGenerator)
let itr = myGenerator()
console.log(itr)
while(i = itr.next()) {
    if (i.done) break
    console.log(i)
}
[GeneratorFunction: myGenerator]
Object [Generator] {}
{ value: 'A', done: false }
{ value: 'B', done: false }
{ value: 'C', done: false }
  • イテレータの特徴である、doneがあるので、間違いなくイテレータですね。
  • 今まで、Array, Map, String などイテレータブルなオブジェクトをvaluesメソッドでイテレータに変換してきましたが、ジュネレータは、最初からイテレータですね。
function* count(value) {
    while(value >= 0) {
        yield value--
    }
}

for(let value of count(10)) {
    console.log(value)
}
  • 引数が設定できる分、先程の例よりも良いコードですね。
  • クラス定義でジュネレータを使ったサンプルが載っていました。
class MyClass {
    constructor(...data) {
        this._data = data
    }
    *[Symbol.iterator]() {
        let num = 0
        while(num < this._data.length) {
            yield this._data[num++]
        }
    }
}

const array = ["AAA", "BBB", "CCC"]
const mc = new MyClass(...array)

for(let value of mc) {
    console.log(value)
}
  • 前回のイテレーターのクラス定義より、ジュネレータのクラス定義のほうがスマートですね。
  • ジェネレータ処理は、非同期でも問題なく処理できるみたいです。
    • 疑似非同期hoge関数を3回呼び出しているだけです。
    • fetchで適当なurlを呼び出してもいいかと思います。
function hoge(value, time=2000) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {  // 時間がかかる処理
      if (value) {
        resolve(`** ${value} **`);
      } else {
        reject(new Error('入力値が空'));
      }
    }, time)
  })
}


async function* asyncJene() {
    for (let i=1; i<4; i++) {
        let result = await hoge('toto')
        yield result
    }
}

async function asyncFunc() {
    for await (let value of asyncJene()) {
        console.log(value)
    }
}
asyncFunc();
  • async await をつけているだけなので、非同期だからといって特別面倒でもないですね。

  • この本は、まだモジュールやbabelの取扱が残っていますが、ここまでで終わりとしたいと思います。

  • 次回もJS関係の本を読み漁りたいと思います。