ジェネレータ

(Web関連用語)
https://developer.mozilla.org/ja/docs/Web/JavaScript/Guide/Iterators_and_generators

通常の関数は、単一の値だけを返す(もしくはなにも返さない)。
ジェネレータは、要求に応じて次々に複数の値、場合によっては無限の数の値を返す(“生み出す”)ことができる。それらは反復可能(iterables)と上手く機能し、データストリームを簡単に作成することができる。

ジェネレータ関数

ジェネレータを作成するには、特別な構文構造: function*、いわゆる “ジェネレータ関数” を使用する必要がある。

function* generateSequence() {
  yield 1;
  yield 2;
  return 3;
}

generateSequence() が呼ばれたとき、コードは実行されない。代わりに、“ジェネレータ”と呼ばれる特別なオブジェクトを返す。
generator オブジェクトは“凍結された関数呼び出し”と捉えることができる。

// "ジェネレータ関数" は "ジェネレータオブジェクト" を生成する。
let generator = generateSequence();

作成時に、コードの実行は最初の部分で一時停止される。
ジェネレータのメインのメソッドは next() である。呼ばれると、最も近い yield 文まで実行を再開する。その後、実行は一時停止し、値は外部のコードに返却される。

例えば、ここではジェネレータを作成し、最初に戻される値を取得している:

function* generateSequence() {
  yield 1;
  yield 2;
  return 3;
}

let generator = generateSequence();
let one = generator.next();
alert(JSON.stringify(one)); // {value: 1, done: false}

next() の結果は常にオブジェクトである:

  • value:戻された値
  • done:コードがまだ終わっていない場合は false、そうでなければ true

再び generator.next() を呼ぶと、実行が再開し、次の yield を貸す:

let two = generator.next();
alert(JSON.stringify(two)); // {value: 2, done: false}

そして、3回目を呼び出すと、実行は関数を終了する return 文に到達する。

let three = generator.next();
alert(JSON.stringify(three)); // {value: 3, done: true}

これでジェネレータが済んだ。done: true でそれが判断でき、value: 3 を最終結果として処理する。
新たな generator.next() 呼び出しはこれ以上意味をなさない。それを行っても、同じオブジェクト {done: true} が返却される。
ジェネレータを “ロールバック” する方法はない。しかし、generateSequence() 呼び出しによって、別の物を作ることはできる。

理解すべき最も重要なことは、ジェネレータ関数は通常の関数とは異なり、コードを実行しないことである。それらは “ジェネレータ工場(ファクトリー)” として機能する。function* の実行はジェネレータを返し、その後、ジェネレータに値を要求する。

inserted by FC2 system