くらげになりたい。

くらげのようにふわふわ生きたい日曜プログラマなブログ。趣味の備忘録です。

Promise.allで並列数を制限する(supercharge/promise-pool)

並列実行できるPromise.all
便利だけど、リストが多いと、並列数がすごくなるので、
制限したいなと思ったときに、いろいろ調べたときの備忘録。

@supercharge/promise-poolを使うとよさそう(´ω`)

インストール

$ npm i @supercharge/promise-pool

使い方

公式のサンプルより。使い方はこんな感じ。
並列数は2の例。

import { PromisePool } from "@supercharge/promise-pool"

const users = [
  { name: 'Marcus' },
  { name: 'Norman' },
  { name: 'Christian' }
]

const { results, errors } = await PromisePool
  .for(users) // 対象のリストを指定
  .withConcurrency(2) // 並列数を指定
  .process(async (userData, index, pool) => {
    // 処理を指定
    const user = await User.createIfNotExisting(userData)
    return user
  })

結果のリストのresultsと、
エラーのリストのerrorsが返ってくる。

例外時のハンドリングもカスタムできるけど、
errorsが返されず、自前で用意する必要があるので注意。

const errors = []
const { results } = await PromisePool
  .for(users) // 対象のリストを指定
  .withConcurrency(2) // 並列数を指定
  .handleError(async (error, user, pool) => {
    // エラー時の処理を指定
    if (error instanceof SomethingBadHappenedError) {
      // 手動での処理の停止
      pool.stop()
    }
    
    // handleErrorを指定すると、errorsを返さないので自前で実装
    errors.push(error)
  })
  .process(async (userData, index, pool) => {
    // 処理を指定
    const user = await User.createIfNotExisting(userData)
    return user
  })

中身は、並列数が上限を超えると、
Promise.race()を使って終了を待つ感じになっていた。

Promise.race() - JavaScript | MDN

以上!!

参考にしたサイトさま