QuestQueue
同時実行数に上限のある、非同期タスクのキューです。同時に走るのは多くても simultaneous 個で、残りは待ち、ひとつ終わるたびに空いた枠が埋まります。まとめてのアップロードやリクエストなど、一度に全部は投げられない場面で使ってください。
API
new QuestQueue({ simultaneous })
| パラメーター | 説明 | 型 | 既定値 |
|---|---|---|---|
simultaneous | 同時実行数の上限。<= 0 は 1 とみなされます | number | 1 |
| メンバー | 説明 |
|---|---|
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();補足
- 先入れ先出し:タスクは積んだ順に走ります。
- ひとつ失敗してもキューは止まりません。 各タスクは自分の Promise だけを reject し、次のタスクはかまわず走り始めます。
- 同期的に例外を投げるタスクも捕まえます。 ですから
add()の外へ漏れて、同時実行数のカウンターが詰まったままになることはありません。 allSettledは渡した順を保ち、それぞれの結果を別々に報告します。
0.3 で書き直しました
以前の実装は使いものになりませんでした。add() は積むだけで、走らせるには自分で running() を呼ぶ必要がありました。取り出しは後入れ先出しで、ひとつの Promise が無関係なタスクの結果まで運び、allSettled は結果を添字 1 から書き込んだうえ、最初のタスクで解決してしまいました。コンストラクターの total オプションはなくなりました。代わりに onIdle() か allSettled(tasks) を使ってください。