この解答例はChatGPTによって生成されています,正しいかは自己判断で。

BFE.devでのAI解答例 - JavaScript コーディング問題
92. Promiseをthrottleする


function throttlePromises(promisesArr, maxConcurrency) {
  return new Promise((resolve, reject) => {
    const results = [];
    let currentIndex = 0;
    let processData = () => {
      while (maxConcurrency > 0 && currentIndex < promisesArr.length) {
        maxConcurrency--;
        const promise = promisesArr[currentIndex];
        promise().then((result) => {
          results[currentIndex] = result;
          maxConcurrency++;
          currentIndex++;
          processData();
        }).catch((err) => {
          reject(err);
        })
        currentIndex++;
      }
      if (currentIndex >= promisesArr.length) {
        resolve(results);
      }
    }
    processData();  
  });
}

解説:

  • throttlePromises() 関数を定義してください。 この関数は、promiseを返す一連の関数を含む配列と、同時進行できるAPIの最大数を受け取ります。
  • maxConcurrency と promisesArr 配列内の各関数は、この関数が実行されたスコープ内で使用されるインデックスを追跡するために使用されます。 currentIndex は、現在の実行済み関数を示します。
  • 関数の内部で、 promisesArr 内の関数を順番に実行する必要があります。
  • そのために、関数の最初の processData() 関数呼び出しを用意します。この関数は、同時に実行できる関数の最大数(maxConcurrency)がある場合、次の関数を直ちに実行することで、非同期プロセスを制御します。 1つの関数が完了すると、同時実行数が1増加し、次の関数がすぐに実行され、以前に完了したのでなければ、別の関数が実行されます。
  • 処理が進むにつれて、currentIndex のインクリメントが進むことになるため、promise.catchで例外を捕捉して reject 呼び出しをする必要があります。そのために resolve と reject メソッドを使用してそれぞれ正常処理と異常処理を処理します。
  • 最後に、processData () 関数が再帰的に呼ばれ、空きスロットを利用して新しいプロミスが起動可能か調べます。プロミスがすべて処理されるまで、プロミスの中にあるthen()コールバックが resolve になるまで待機します。 つまり、同時に maxConcurrency 数量分までリクエストを送信し続け、すべてのリクエストが完了すると、Promise.all と同様に配列に1つずつ受け取った結果を順に保持し、結果を解決するようにしています。