JavaScript/ジェネレータ関数
表示
ジェネレータ関数
[編集]ジェネレータ関数は、JavaScript で非同期処理や遅延実行を管理するために使用される特殊なタイプの関数です。通常の関数とは異なり、ジェネレータ関数は一時停止してその後再開でき、呼び出し元とデータをやり取りすることができます。これを実現するために、function*
構文を使用します。ジェネレータ関数は、yield
キーワードを使って実行を一時停止し、next()
メソッドを使って再開できます。
構文
[編集]function* generatorFunction() { // 実行するコード }
この構文で定義された関数は、通常の関数とは異なり、呼び出すとジェネレータオブジェクトを返します。このオブジェクトは、next()
メソッドを用いて逐次実行できます。
使用例
[編集]基本的な使用例
[編集]ジェネレータ関数を呼び出すと、ジェネレータオブジェクトが返され、そのオブジェクトの next()
メソッドを使って順次実行することができます。
function* count() { yield 1; yield 2; yield 3; } const gen = count(); console.log(gen.next().value); // 1 console.log(gen.next().value); // 2 console.log(gen.next().value); // 3 console.log(gen.next().done); // true
この例では、count 関数はジェネレータであり、yield
によって途中で一時停止し、next()
メソッドを使って再開できます。
引数を渡す
[編集]next()
メソッドには引数を渡すことができ、これによりジェネレータ関数内の yield
に値を送信できます。
function* process() { const value = yield 'Start'; console.log('Received:', value); yield 'End'; } const gen = process(); console.log(gen.next().value); // 'Start' gen.next('Received value'); // 'Received: Received value' console.log(gen.next().value); // 'End'
この例では、gen.next('Received value')
で渡された引数が value
に設定され、console.log
によってその値が出力されます。
ジェネレータ関数は return
を使って値を返すこともできます。この場合、done
プロパティが true
となり、ジェネレータが終了したことを示します。
function* count() { yield 1; yield 2; return 'done'; } const gen = count(); console.log(gen.next()); // { value: 1, done: false } console.log(gen.next()); // { value: 2, done: false } console.log(gen.next()); // { value: 'done', done: true } console.log(gen.next()); // { value: undefined, done: true }
この例では、return
によって 'done'
が返され、ジェネレータの終了が確認できます。
ジェネレータ関数の特徴
[編集]- 一時停止と再開:
yield
を使って関数の実行を一時停止し、next()
メソッドで再開することができます。 - 遅延評価: ジェネレータ関数は、要求された時にのみ計算を行う「遅延評価」が可能です。これにより、必要な時にのみデータを生成することができます。
- 非同期処理: 非同期処理の管理に役立ちます。例えば、非同期のループ処理や状態管理をジェネレータ関数で行うことができます。
使用シーン
[編集]ジェネレータ関数は、主に次のようなシーンで使用されます。
- 遅延データ処理: 大量のデータを一度に処理するのではなく、必要な部分だけを生成し、メモリ使用量を抑えることができます。
- 非同期処理の管理:
async/await
より前のバージョンでは、非同期処理の流れをジェネレータで制御することが一般的でした。 - シンプルな状態管理: ジェネレータは、状態管理やイベント駆動型のプログラムで使われることがあります。
注意点
[編集]- ジェネレータ関数は
yield
で停止し、再開するにはnext()
を明示的に呼び出す必要があります。 - ジェネレータ関数の実行は途中で終了することがあります。
return
を使うことで、終了の合図を出すことができます。 done
プロパティがtrue
である場合、そのジェネレータはすでに終了しており、もう一度実行することはできません。