javascript:generator
文書の過去の版を表示しています。
Generator
Generator(ジェネレータ)はECMAScript 6で追加された新機能。
ジェネレータは、内部の状態管理が必要となるIterator(イテレータ)の反復処理において、オブジェクトよりも簡単・安全に状態管理を行うための機能である。
ジェネレータを用いた反復処理では「次の値の取り出し」と「取り出した値の処理」が交互に繰り返される。「次の値の取り出し」を行った後「取り出した値の処理」が完了するまでジェネレータ関数に記述された手続きの流れが一時中断される。
今までのJavaScriptでは実現できなかった手続き途中での中断という動作が非同期処理のより良いコーディング手法として注目されている。
ジェネレータの動作
function* f() { yield "a"; yield "b"; yield "c"; } var g = f(); // g => [Object: generator] console.log(g.next()); // => { value: "a", done: false } console.log(g.next()); // => { value: "b", done: false } console.log(g.next()); // => { value: "c", done: false } console.log(g.next()); // => { value: undefined, done: true }
- キーワード
function*
でジェネレータ関数を定義 - ジェネレータ関数を実行するとGeneratorオブジェクトが得られる。
- Generator#nextを呼ぶとジェネレータ関数の最初のyield式まで実行され、nextがyield式の評価結果を返す。
- 再度Generator#nextを呼ぶと次のyield式まで実行される
- 繰り返し
- Generator#nextが呼ばれ、ジェネレータ関数の末尾まで到達すると
{ value: undefined, done: true }
を返す
ジェネレータの例
フィボナッチ数列を生成するジェネレータ
function* fibonacci(limit = Infinity) { var count = 0; var a = 1; var b = 1; while(count++ < limit) { let c = a + b; a = b; b = c; yield c; } } for (let i of fibonacci(5)) { console.log(i) }
結果
2 3 5 8 13
Rangeを生成するジェネレータ
function* range(a, b) { for(var i = a; i <= b; i++) { yield i; } } for (let i of range(3,7)) { console.log(i) }
結果
3 4 5 6 7
非同期処理
ジェネレータを用いた非同期処理
var g = (function* () { console.log(1); var x = yield setTimeout(function() { console.log(2); g.next(3); }, 1000); console.log(x); var y = yield setTimeout(function() { console.log(4); g.next(5); }, 2000); console.log(y); })(); g.next();
結果
1 // ここで1秒待つ 2 3 // ここで2秒待つ 4 5
javascript/generator.1388501067.txt.gz · 最終更新: 2013/12/31 14:44 by nullpon