2.1 ジェネレーターの構文
JavaScriptのジェネレーターは特別な関数で、コードの実行を管理することができるよ。 実行を一時停止したり後で再開したりできるから、非同期コードやイテレーター、その他の複雑なタスクを扱う強力なツールなんだ。
ジェネレーターは function*
(アスタリスクに注目)を使って定義されるよ。
ジェネレーターの中では、yield
演算子を使って実行を一時停止して値を返すんだ。
ジェネレーターの宣言:
function* generatorFunction() {
yield 1;
yield 2;
yield 3;
}
ジェネレーターオブジェクトの生成
ジェネレーターを呼び出すと、その本体はすぐには実行されない。代わりにジェネレーターオブジェクトを返すので、 これを使って値を順番に取得することができるんだ。
const gen = generatorFunction();
2.2 ジェネレーターの使い方
メソッド next()
next()
メソッドは、ジェネレーターの実行を次の yield
演算子まで再開するために使うんだ。
このメソッドは2つのプロパティを持つオブジェクトを返すよ:
value
:yield
演算子によって渡された値done
: ジェネレーターが終了したかどうかを示す真偽値 (true
なら終了、false
なら未終了)
メソッド next() の使い方の例:
function* generatorFunction() {
yield 1;
yield 2;
yield 3;
}
const gen = generatorFunction();
console.log(gen.next()); // { value: 1, done: false }
console.log(gen.next()); // { value: 2, done: false }
console.log(gen.next()); // { value: 3, done: false }
console.log(gen.next()); // { value: undefined, done: true }
ジェネレーターの反復処理
ジェネレーターは for...of
ループと一緒に使って、値を順番に取得することができるよ。
ジェネレーターを使った反復処理の例:
function* generatorFunction() {
yield 1;
yield 2;
yield 3;
}
const gen = generatorFunction();
for (const value of gen) {
console.log(value);
}
// 出力される: 1
// 出力される: 2
// 出力される: 3
値の返却例
ジェネレーターは return
演算子を使って値を返すことができるよ:
function* generatorFunction() {
yield 1;
yield 2;
return 3;
yield 4; // この yield は実行されない
}
const gen = generatorFunction();
console.log(gen.next()); // { value: 1, done: false }
console.log(gen.next()); // { value: 2, done: false }
console.log(gen.next()); // { value: 3, done: true }
console.log(gen.next()); // { value: undefined, done: true }
2.3 ジェネレーターの高度な使い方
ジェネレーターとの対話
next()
メソッドは引数を受け取り、これをジェネレーターに渡し内部で使用することができる。
ジェネレーターに値を渡す例:
function* generatorFunction() {
const value1 = yield 1;
const value2 = yield value1 + 2;
yield value2 + 3;
}
const gen = generatorFunction();
console.log(gen.next()); // { value: 1, done: false }
console.log(gen.next(10)); // { value: 12, done: false }
console.log(gen.next(20)); // { value: 23, done: false }
console.log(gen.next()); // { value: undefined, done: true }
エラー処理
ジェネレーターでは try...catch
ブロックを使用してエラーを処理することができる。
エラー処理の例:
function* generatorFunction() {
try {
yield 1;
yield 2;
} catch (error) {
console.log('Error caught:', error);
}
}
const gen = generatorFunction();
console.log(gen.next()); // { value: 1, done: false }
console.log(gen.throw(new Error('Something went wrong'))); // Error caught: Error: Something went wrong
// { value: undefined, done: true }
無限シーケンスを生成するジェネレーターの例
ジェネレーターを使って無限シーケンスを生成することができる。
function* infiniteSequence() {
let i = 0;
while (true) {
yield i++;
}
}
const gen = infiniteSequence();
console.log(gen.next().value); // 0
console.log(gen.next().value); // 1
console.log(gen.next().value); // 2
// と続く
2.4 実際の使用例
例1: オブジェクトを反復するジェネレーター
function* objectEntries(obj) {
const keys = Object.keys(obj);
for (const key of keys) {
yield [key, obj[key]];
}
}
const obj = { a: 1, b: 2, c: 3 };
const gen = objectEntries(obj);
for (const [key, value] of gen) {
console.log(`${key}: ${value}`);
}
// 出力される:
// a: 1
// b: 2
// c: 3
例2: 簡単なイテレーターを実装するジェネレーター
const myIterable = {
*[Symbol.iterator]() {
yield 1;
yield 2;
yield 3;
}
};
for (const value of myIterable) {
console.log(value);
}
// 出力される: 1
// 出力される: 2
// 出力される: 3
JavaScriptのジェネレーターは、コードの実行を管理し、イテレーターや非同期操作を扱うための強力なツールだよ。 ジェネレーターの構文と使い方を理解することで、特にデータのシーケンスや非同期タスクにおいて、より柔軟で読みやすいコードを書くことができるんだ。
GO TO FULL VERSION