はじめに

今回はJavascriptのGeneratorに付いて触れていきます。理解するのに時間がかかった上、実務で弄ったことがないので間違えている箇所があればコメントでご指摘いただけると幸いです。

ジェネレータとは

一言でいうと何回でも処理の途中で抜けたり入ったりできる関数の事。for of文と相性が良く、実装次第では自分の意図する等に処理できる。

ジェネレーターを作ってみる

下記の通り、functionの後に*を付けて宣言すればジェネレータの完成です。

javascript.js
function* numbers(){
    yield;
 }

証拠に下記の通り、このジェネレータをコンソール上に出力すればジェネレーターが作成されていることがわかります。

javascript.js
console.log(numbers()); //=> __proto__: Generator が生成される。

関数の中に記述されているyieldは通常の関数で使われているreturnの代わりになるものでnextメソッドを使うたびに実行してくれます。

下記が例の構文です。

javascript.js
function* colors(){
   yield 'red';
   yield 'blue';
   yield 'green';
}

const colorGen = colors();
console.log(colorGen.next()); //{value: "red", done: false}
console.log(colorGen.next()); //{value: "blue", done: false}
console.log(colorGen.next()); //{value: "green", done: false}
console.log(colorGen.next()); //{value: undefined, done: true}

見てもらえればわかる通り、1回目のnextメソッド実行時にcolorsジェネレーターの処理内の一つ目のyieldが実行されており、2回目、3回目と実行するたびに今度はbluegreenが出力されるようになりました。注目していただきたいのがnextメソッドの返り値は常にvaluedoneプロパティからなるオブジェクトを返しており、yieldの返り値がある時はfalseとなっていますが返り値がなくなるとtrueを返しています。

generatorの実行途中に任意の値を渡せる

上記の例文でgeneretorの実行の方法と返り値を知ることができました。今度は上の例文にまた処理を付け加えて一癖加えていきたいと思います。

javascript.js
function* shopping(){

    const stuffFromStore = yield 'お金' ;
    const clothes = yield '';
    return [stuffFromStore, clothes]; 
 }

const shoppingGen = shopping();
 console.log(shoppingGen.next()); // {value: "お金", done: false} ---(1)
 console.log(shoppingGen.next('品物')); //{value: "服", done: false} ---(2)
 console.log(shoppingGen.next('綺麗な服')); //{value: Array, done: true} ,value: ["品物", "綺麗な服"]

上の処理中の(1)は単純にnextメソッドを呼び出し、最初のyieldまで処理しています。よって出力結果は普通にお金が出力されるはずです。次の(2)の処理ですがここではnextメソッドを呼び出す際に引数に品物を渡しています。このnextメソッドの呼び出しによって今度はyield 'お金'以降から処理が再開されるのですがこの時に品物が定数stuffFromStoreに入っていきます。
以降同じように処理しておくと最後のreturn文では品物綺麗な服の配列を返すようになりました。

このようにgeneretorを使うことによって処理の途中に任意の変数を代入して処理結果を変えることができることがわかりました。

最後

今回はgeneratorの基礎の部分について復習してみました。長くなるので実際の応用方法は次回の記事に回します。
ありがとうございました。