kasei_sanのブログ

かせいさんのIT系のおぼえがきです。胡乱の方はnoteとtwitterへ

javascript の generator おぼえがき

ECMAScript 6 にて実装された

generator って?

generatorそのものの解説はこちらが詳しい

Pythonのジェネレーターってなんのためにあるのかをなるべく分かりやすく説明しようと試みた - Qiita

  • 要するに、ステートを持ち、呼ばれるたびにそのステートを使った処理結果を返すオブジェクト
  • 超でかいファイルを1行づつ読み込む時とか、必要な時に必要なだけ実行される処理が欲しい時に使う
  • rubyだと Enumerator::Lazy とかが近い?

実装方法

generator関数

  • generatorを生成する関数
  • generator関数は function* で宣言できる
  • generator関数の中では、yield を設定できる(後述)

generator

  • generator関数 の戻り値として生成される
  • next() を実行すると、generator関数で設定した yield のところまで実行される
  • next() の戻り値は、 valuedone のキーを持つ Hash
    • value : yield の引数
    • done
      • なにか処理が実行されていれば true
      • 何も処理が実行されていれば false

サンプル

function* generator(){
  yield 1;
  yield 2;
  yield 3;
}

g = generator();

console.log(g.next());
console.log(g.next());
console.log(g.next());
console.log(g.next());
console.log(g.next());
{ value: 1, done: false }
{ value: 2, done: false }
{ value: 3, done: false }
{ value: undefined, done: true }
{ value: undefined, done: true }

サンプル2

遅延評価的なことをやってみる

function* fibonacci_generator(){
  var a = 0;
  var b = 1;

  while(true) {
    const c = b
    b = a + b;
    a = c;
    yield b
  }
}

const fibonacci = fibonacci_generator();

for(var i=0; i<10; i++){
  console.log(fibonacci.next());
}
{ value: 1, done: false }
{ value: 2, done: false }
{ value: 3, done: false }
{ value: 5, done: false }
{ value: 8, done: false }
{ value: 13, done: false }
{ value: 21, done: false }
{ value: 34, done: false }
{ value: 55, done: false }
{ value: 89, done: false }

こっちは終わらない処理なので、 done はずっと false