実装
const promiseAllWithConcurrencyLimit =
async <T>(promises: (() => Promise<T>)[], concurrency: number) => {
const results: T[] = []
let idx = 0
await Promise.all(Array.from({ length: concurrency }).map(async () => {
while (true) {
const cur = idx++
const task = promises[cur]
if (!task) return
results[cur] = await task()
}
}))
return results
}
記事を書くまでの経緯
こちらの記事の実装の場合
[6秒かかる処理, 2秒かかる処理, 2秒かかる処理, 2秒かかる処理]
を concurrency = 2
で実行すると 8 秒かかります。
上記の実装の場合 6 秒ですみます。
解説
Promise
を concurrency
の指定数生成する。
各 Promise
は下記を行う。
-
promises
に処理が残っていなかったら終了。 -
promises
から処理を取り出して実行する。 -
1.
に戻る。
これにより、 Promise
の数だけ並行して処理が走る。
( Promise
内では await
の指定により同期的に走るため数を超えない )