この解答例は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つずつ受け取った結果を順に保持し、結果を解決するようにしています。