最終更新
最終更新
function *
は_ジェネレータ関数_の作成に使う構文です。ジェネレータ関数を呼び出すと、_ジェネレータオブジェクト_が返されます。ジェネレータオブジェクトは、インターフェースに準拠しています(つまりnext
、return
およびthrow
関数を実装しています)。
ジェネレータが必要となる背景には2つの重要な動機があります。
ジェネレータ関数を使用して遅延評価されるイテレータを作成することができます。次の関数は、必要なだけの整数の無限リストを返します:
もちろんイテレータが終了した場合は、以下に示すように{ done: true }
の結果を得られます。
これはジェネレータの真にエキサイティングな部分です。本質的には、関数がその実行を一時停止し、残りの関数実行の制御(運命)を呼び出し元に渡すことができます。
ジェネレータ関数は、呼び出した時には実行されません。単にジェネレータオブジェクトを作るだけです。サンプルの実行とともに次の例を考えてみましょう:
これを実行すると、次の出力が得られます。
関数はジェネレータオブジェクトに対してnext
が呼び出された時に1回だけ実行されます
関数はyield
文が出現するとすぐに一時停止します
関数はnext
が呼び出されたときに再開します
つまり、基本的にジェネレータ関数の実行は、ジェネレータオブジェクトによって制御することができます。
ここまで、ジェネレータを使った通信は、ほとんどがジェネレータがイテレータの値を返す、一方向のものでした。JavaScriptのジェネレータの非常に強力な機能の1つは、双方向の通信を可能にすることです!
iterator.next(valueToInject)
を使って、yield
式の返却値を制御することができます
iterator.throw(error)
を使ってyield
式の位置で例外を投げることができます
次の例は iterator.next(valueToInject)
を示しています:
次の例は iterator.throw(error)
を示しています:
まとめると、このようになります:
yield
は、ジェネレータ関数の通信を一時停止し、関数の外部に制御を渡すことを可能にします
外部から、ジェネレータ関数本体に値を送ることができます
外部から、ジェネレータ関数本体に対して例外をthrow
することができます
これが、どのように便利なのでしょうか? 次のセクションでそれを説明します。