「労働者が自分の仕事をうまくやりたいなら、まず自分の道具を研ぎ澄まさなければなりません。」 - 孔子、「論語。陸霊公」
表紙 > プログラミング > JavaScript ジェネレーターを理解する: 強力なコード フロー制御ツール

JavaScript ジェネレーターを理解する: 強力なコード フロー制御ツール

2024 年 11 月 8 日に公開
ブラウズ:912

Razumevanje JavaScript Generatora: Moćan Alat za Kontrolu Toka Koda

ジェネレーターは JavaScript の最も強力な機能の 1 つで、必要に応じて一時停止および再開できるコードを作成できます。すべてのコードを一度に実行する通常の関数とは異なり、ジェネレーターは遅延実行を使用し、値を段階的に返すため、データ シーケンス、反復、または長時間実行プロセスの操作が容易になります。

発電機はどのように動作するのですか?

JavaScript では、ジェネレーターは function* キーワードを使用して定義され、yield キーワードと組み合わせることで、関数を部分的に実行できます。ジェネレーター関数を呼び出すたびに、すぐには実行されませんが、制御された実行を可能にするイテレーターが返されます。

例:

const id = (function* () {
    let i = 1;
    while (true) {
        yield i;
        i  = 1;
    }
})();

この例では、ファンクション ジェネレーターは無限の数値シーケンスを返します。各数値は生成され、必要な場合にのみ返されます。

yield は何をしますか?

yield キーワードはジェネレーターの実行を停止し、値を外部に返します。次の関数呼び出し (next() を使用) で、ジェネレーターは中断したところから続行します。

ジェネレーターの呼び出しは次のようになります:

console.log(id.next().value); // 1
console.log(id.next().value); // 2
console.log(id.next().value); // 3

next() を呼び出すたびに、配列の次の値が返され、次の yield で関数が一時停止されます。

ジェネレーターの利点

  • 怠惰:
    ジェネレーターはすべてを一度に実行するのではなく、必要なときにのみ値を生成します。これは、無限のシーケンスや大規模なデータ配列を扱う場合に最適です。

  • フロー制御:
    関数を一時停止および再開できるため、長時間実行プロセスをより適切に制御できます。

  • 効率:
    すべての値をメモリに保存するのではなく、ジェネレータは一度に 1 つを返すため、メモリの消費量が削減されます。

ジェネレーターのデメリット

ジェネレーターは便利ですが、いくつかの潜在的な問題があります:

  • 複雑なフロー制御:
    一時停止と再開を行うと、特に複雑なシナリオでは、コードの理解とデバッグが困難になる可能性があります。

  • パフォーマンス:
    場合によっては、コードを一時停止して再開すると追加のオーバーヘッドが発生し、効率が低下する可能性があります。

  • 限定:
    呼び出しごとに 1 つの値が返されるため、一度に大量のデータにアクセスする必要がある場合は非効率的になる可能性があります。

  • 互換性:
    ジェネレーターは ECMAScript 2015 (ES6) 標準の一部であるため、古いブラウザーでは、Babel.

  • のような追加ツールがないとジェネレーターをサポートできない可能性があります。

代替アプローチ

ジェネレーターが複雑すぎる場合は、代替手段を検討できます:

コールバックを伴う再帰関数:

function generateID(callback, start = 1) {
    callback(start);
    setTimeout(() => generateID(callback, start   1), 0);
}
  • 利点:
    より簡単なフロー制御: 再帰を使用していますが、プログラムのフロー制御という点では、関数はより読みやすく明確です。
    非同期実行: setTimeout を使用すると非同期操作が有効になり、パフォーマンスの維持に役立ちます。

  • 欠点:
    再帰のオーバーヘッド: 反復回数が非常に多い場合、再帰の問題 (スタック オーバーフロー) が発生する可能性があります。

ループ:
所定の数の値を生成する単純なループは、小さな配列の場合により効率的なオプションとなる可能性があります。

function generateIDs(limit) {
    const ids = [];
    for (let i = 1; i 



  • 利点:
    シンプルな実装: このソリューションは理解しやすく、フロー制御に問題はありません。
    高速生成: すべての値が一度に生成されるため、反復回数が少なくなり、より効率的になります。

  • 欠点:
    メモリ消費量: すべての値はメモリに保存されるため、大規模な配列では問題になる可能性があります。
    怠惰なし: すべての ID が事前に生成されるため、すべてが必要でない場合は非効率になる可能性があります。

イテレータ:
.next() メソッドを通じて反復可能な値を返すオブジェクト。ジェネレーターに似ていますが、より詳細な制御が可能です。

function createIDIterator() {
    let i = 1;
    return {
        next() {
            return { value: i  , done: false };
        }
    };
}

const idIterator = createIDIterator();

console.log(idIterator.next().value); // 1
console.log(idIterator.next().value); // 2
console.log(idIterator.next().value); // 3
  • 利点:
    フロー制御: ジェネレーターと同様の機能がありますが、実行はより直線的です。
    よりシンプルなコード: イールドがないため、コードを理解しやすくなります。

  • 欠点:
    自動一時停止なし: 繰り返しを手動で管理する必要があり、場合によっては不便になる可能性があります。

async/await による非同期生成
ID が非同期で生成される場合は、Promise を返す関数で async/await を使用できます。

async function generateID(start = 1) {
    let i = start;
    while (true) {
        await new Promise((resolve) => setTimeout(resolve, 0));
        console.log(i  );
    }
}

generateID(); 
  • 利点:
    非同期実行: 実行のメイン フローをブロックすることなく、長時間実行される操作を効率的に処理します。
    最新の構文: async/await は、非同期コードを操作するためのより現代的で直感的な方法です。

  • 欠点:
    同期コードには適していません: 同期生成が必要な場合、このソリューションは理想的ではありません。

結論

ジェネレーターは、大規模で無限のデータ配列を操作したり、プロセスの一時停止と再開が必要なアプリケーションのフロー制御に優れたツールです。ただし、その複雑さとパフォーマンス上の問題が発生する可能性があるため、使用には注意が必要です。アプリケーションの要件によっては、反復、再帰、非同期コードなどの代替ソリューションの方が適切な場合があります。

リリースステートメント この記事は、https://dev.to/jelena_petkovic/razumevanje-javascript-generatora-mocan-alat-za-kontrolu-toka-2hpo?1に再現されています。
最新のチュートリアル もっと>

免責事項: 提供されるすべてのリソースの一部はインターネットからのものです。お客様の著作権またはその他の権利および利益の侵害がある場合は、詳細な理由を説明し、著作権または権利および利益の証拠を提出して、電子メール [email protected] に送信してください。 できるだけ早く対応させていただきます。

Copyright© 2022 湘ICP备2022001581号-3