ecmascript:generator
差分
このページの2つのバージョン間の差分を表示します。
| 次のリビジョン | 前のリビジョン | ||
| ecmascript:generator [2015/10/24 04:29] – 作成 nullpon | ecmascript:generator [2025/09/15 15:59] (現在) – nullpon | ||
|---|---|---|---|
| 行 1: | 行 1: | ||
| ====== Generator ====== | ====== Generator ====== | ||
| - | Generator(ジェネレータ)はECMAScript 6で追加された新機能。 | + | Generator(ジェネレータ)関数は[[./ |
| - | ジェネレータは、内部の状態管理が必要となるIterator(イテレータ)の反復処理において、オブジェクトよりも簡単・安全に状態管理を行うための機能である。 | + | ジェネレータは、特別なキーワード'' |
| - | + | ||
| - | ジェネレータを用いた反復処理では「次の値の取り出し」と「取り出した値の処理」が交互に繰り返される。「次の値の取り出し」を行った後「取り出した値の処理」が完了するまでジェネレータ関数に記述された手続きの流れが一時中断される。 | + | |
| - | + | ||
| - | 今までのJavaScriptでは実現できなかった手続き途中での中断という動作が非同期処理のより良いコーディング手法として注目されている。 | + | |
| ===== ジェネレータの動作 ===== | ===== ジェネレータの動作 ===== | ||
| <code javascript> | <code javascript> | ||
| - | function* | + | function* |
| - | | + | yield 1; |
| - | y = yield ++i; | + | yield 2; |
| - | | + | yield 3; |
| - | y = yield ++i; | + | |
| - | | + | |
| - | y = yield ++i; | + | |
| - | console.log(y); // => " | + | |
| } | } | ||
| - | var g = f(1); // g => [Object: generator] | ||
| - | console.log(g.next()); | ||
| - | console.log(g.next(" | ||
| - | console.log(g.next(" | ||
| - | console.log(g.next(" | ||
| - | </ | ||
| - | |||
| - | - キーワード '' | ||
| - | - ジェネレータ関数を実行するとGeneratorオブジェクトが得られる | ||
| - | * この時点ではジェネレータ関数の中身は実行されない | ||
| - | * 引数 1 はジェネレータ関数に渡される | ||
| - | - Generator# | ||
| - | * Generator# | ||
| - | - 再度 Generator# | ||
| - | * 最初の yield が next の引数(" | ||
| - | * ジェネレータ関数が次の yield 式まで実行される。 | ||
| - | * Generator# | ||
| - | - 再度 Generator# | ||
| - | * 二番目の yield が next の引数(" | ||
| - | * ジェネレータ関数が次の yield 式まで実行される。 | ||
| - | * Generator# | ||
| - | - さらに Generator# | ||
| - | * 三番目の yield が next の引数(" | ||
| - | * ジェネレータ関数の末尾まで実行される。 | ||
| - | * Generator# | ||
| + | for (const i of generator()) { | ||
| + | | ||
| + | } | ||
| + | </ | ||
| ===== ジェネレータの例 ===== | ===== ジェネレータの例 ===== | ||
| 行 53: | 行 24: | ||
| <code javascript> | <code javascript> | ||
| - | function* fibonacci(limit = Infinity) { | + | function* fibonacci(count = Infinity) { |
| - | | + | |
| - | var a = 1; | + | |
| - | var b = 1; | + | |
| - | | + | |
| - | | + | |
| - | a = b; | + | |
| - | | + | |
| - | yield c; | + | |
| } | } | ||
| } | } | ||
| - | for (let i of fibonacci(5)) { | + | for (let i of fibonacci(10)) { |
| - | | + | |
| } | } | ||
| + | |||
| </ | </ | ||
| - | 結果 | + | |
| - | < | + | |
| - | 2 | + | |
| - | 3 | + | |
| - | 5 | + | |
| - | 8 | + | |
| - | 13 | + | |
| - | </ | + | |
| Rangeを生成するジェネレータ | Rangeを生成するジェネレータ | ||
| 行 88: | 行 49: | ||
| for (let i of range(3,7)) { | for (let i of range(3,7)) { | ||
| - | | + | |
| } | } | ||
| </ | </ | ||
| - | 結果 | ||
| - | < | ||
| - | 3 | ||
| - | 4 | ||
| - | 5 | ||
| - | 6 | ||
| - | 7 | ||
| - | </ | ||
| - | |||
| - | ===== 非同期処理 ===== | ||
| - | |||
| - | ジェネレータを用いた非同期処理 | ||
| - | |||
| - | <code javascript> | ||
| - | var g = (function* () { | ||
| - | | ||
| - | var x = yield setTimeout(function() { console.log(2); | ||
| - | | ||
| - | var y = yield setTimeout(function() { console.log(4); | ||
| - | | ||
| - | })(); | ||
| - | g.next(); | ||
| - | </ | ||
| - | 結果 | ||
| - | < | ||
| - | 1 // ここで1秒待つ | ||
| - | 2 | ||
| - | 3 // ここで2秒待つ | ||
| - | 4 | ||
| - | 5 | ||
| - | </ | ||
| - | |||
ecmascript/generator.1445660989.txt.gz · 最終更新: by nullpon