INDEX
yieldの概要
| ジェネレーター制御 JavaScript予約語 | ||
|
yield 値 概要 わかりやすく説明 |
||
|
yieldの基本的な使い方
以下の例は、ジェネレーター関数の基本的な使い方を示しています。
// 基本的なジェネレーター関数
function* simpleGenerator() {
console.log("ジェネレーター開始");
yield 10; // 一時停止して10を返す
console.log("1つ目のyieldを通過");
yield 20; // 次に20を返す
console.log("2つ目のyieldを通過");
}
// ジェネレーターオブジェクトの作成
const generator = simpleGenerator();
console.log(generator.next()); // { value: 10, done: false }
console.log(generator.next()); // { value: 20, done: false }
console.log(generator.next()); // { value: undefined, done: true }
- function*を使ってジェネレーター関数を定義します。
yieldは値を返し、実行を一時停止します。generator.next()で実行を再開し、次のyieldまで進みます。- すべての
yieldを通過するとdone: trueが返され、終了します。
ジェネレーターとyieldの動作原理
ジェネレーター関数は、実行を一時停止して再開することで効率的な処理を実現します。その動作原理を見てみましょう。
// next()でデータを注入する例
function* dataProcessor() {
console.log("データ待機中...");
const input = yield "データを送信してください";
console.log(`受け取ったデータ: ${input}`);
yield "完了しました";
}
// 使用例
const processor = dataProcessor();
console.log(processor.next()); // { value: "データを送信してください", done: false }
console.log(processor.next("サンプルデータ")); // { value: "完了しました", done: false }
console.log(processor.next()); // { value: undefined, done: true }
- yieldは実行を停止し、値を返す一方で、次の
next()呼び出し時にデータを受け取ります。 - これにより、関数の外部からデータを注入することができます。
- ジェネレーターはステートマシンとして動作し、内部状態を保持します。
非同期ジェネレーターの詳細
リアルタイムデータやストリーム処理において、非同期ジェネレーターは強力なツールです。
// 非同期ジェネレーターの例
async function* asyncGenerator() {
for (let i = 1; i <= 3; i++) {
await new Promise((resolve) => setTimeout(resolve, 1000)); // 1秒待機
yield i;
}
}
// 使用例
(async () => {
for await (const num of asyncGenerator()) {
console.log(num); // 1, 2, 3 (1秒間隔で出力)
}
})();
- async function*で非同期ジェネレーターを定義します。
- データを非同期に生成し、
for await...ofで繰り返し処理します。 - リアルタイムデータストリームや非同期API呼び出しに活用できます。
yield*の使い方と応用
ジェネレーターの委譲を可能にするyield*の使い方を見てみましょう。
// ジェネレーターの委譲
function* subGenerator() {
yield "A";
yield "B";
}
function* mainGenerator() {
yield* subGenerator(); // サブジェネレーターに委譲
yield "C";
}
// 使用例
for (const value of mainGenerator()) {
console.log(value); // "A", "B", "C"
}
- 複数のジェネレーターを組み合わせて、柔軟なデータフローを実現します。
yield*は別のジェネレーターを展開し、値を順次返します。- ジェネレーターの分割と再利用が容易になります。
実践的なユースケース
以下は、yieldを活用した実践的な例です。
// ページネーションの例
function* paginate(array, size) {
for (let i = 0; i < array.length; i += size) {
yield array.slice(i, i + size); // 指定サイズごとにデータを返す
}
}
// 使用例
const data = [1, 2, 3, 4, 5, 6];
for (const page of paginate(data, 2)) {
console.log(page); // [1, 2], [3, 4], [5, 6]
}
- 大規模データを小分けにして処理します。
- サーバーからのデータ取得やUIの分割表示に活用できます。
yieldにより、遅延評価を実現し、効率的なメモリ管理を可能にします。
yieldの注意点
- 通常の関数では使用できません:
yieldはジェネレーター関数(function*)内でのみ使用可能です。 - 非同期処理には非対応: 非同期処理を行う場合は
async function*を使用してください。 - コードの追跡が難しい場合があります:
yieldの多用は再開ポイントを把握するのが難しくなることがあります。
yieldのよくある質問
- Q:
yieldとreturnの違いは何ですか? - A:
returnは関数の実行を完全に終了しますが、yieldは一時停止し、後で再開することが可能です。 - Q: 非同期ジェネレーターとは何ですか?
- A: 非同期ジェネレーターは、非同期処理で
yieldを使用する仕組みです。async function*で定義し、for await...ofで処理を行います。 - Q:
yield*とは何ですか? - A:
yield*は別のジェネレーター関数の処理を委譲するための構文です。これにより、複数のジェネレーターを組み合わせて使用できます。
まとめ
yieldは、柔軟かつ効率的なデータ処理を可能にするキーワードです。ジェネレーター関数を活用することで、遅延評価や非同期処理、データの動的生成が容易になります。
- 無限シーケンスや大規模データを効率的に処理できます。
- 非同期ジェネレーターを使えば、リアルタイムデータにも対応可能です。
yield*を使うことで、複雑な処理を分割し再利用性を高められます。
適切な用途を見極めて活用することで、プログラムの効率性と可読性を向上させることができます。