Skip to content

QuestQueue

同時実行数に上限のある、非同期タスクのキューです。同時に走るのは多くても simultaneous 個で、残りは待ち、ひとつ終わるたびに空いた枠が埋まります。まとめてのアップロードやリクエストなど、一度に全部は投げられない場面で使ってください。

API

new QuestQueue({ simultaneous })

パラメーター説明既定値
simultaneous同時実行数の上限。<= 0 は 1 とみなされますnumber1
メンバー説明
add(task)タスクを積み、そのタスク自身の 結果の Promise を受け取ります。枠が空き次第、走り始めます
allSettled(tasks)まとめて積みます。Promise.allSettled と同じように、渡した順で解決されます
onIdle()キューが空になるまで待ちます
clear()まだ始まっていないものをすべて捨てます(走っているタスクはそのままです)
running / pending / executed / idle現在の状況を示すカウンター

使用例

js
import { QuestQueue } from 'ranuts';

const queue = new QuestQueue({ simultaneous: 3 });
const results = await Promise.all(urls.map((url) => queue.add(() => fetch(url))));

// あるいは投げっぱなしにして、失敗も含めてすべてを待つ
urls.forEach((url) => queue.add(() => fetch(url)).catch(report));
await queue.onIdle();

補足

  1. 先入れ先出し:タスクは積んだ順に走ります。
  2. ひとつ失敗してもキューは止まりません。 各タスクは自分の Promise だけを reject し、次のタスクはかまわず走り始めます。
  3. 同期的に例外を投げるタスクも捕まえます。 ですから add() の外へ漏れて、同時実行数のカウンターが詰まったままになることはありません。
  4. allSettled は渡した順を保ち、それぞれの結果を別々に報告します。

0.3 で書き直しました

以前の実装は使いものになりませんでした。add() は積むだけで、走らせるには自分で running() を呼ぶ必要がありました。取り出しは後入れ先出しで、ひとつの Promise が無関係なタスクの結果まで運び、allSettled は結果を添字 1 から書き込んだうえ、最初のタスクで解決してしまいました。コンストラクターの total オプションはなくなりました。代わりに onIdle()allSettled(tasks) を使ってください。

MIT ライセンスのもとで公開されています。