以前の回答ですでに述べたように、はPromise.all
すべての解決された値を元のPromiseの入力順序に対応する配列で集約します(Promiseの集約を参照)。
ただし、注文はクライアント側でのみ保存されることを指摘しておきます。
開発者にとって、約束は順調に満たされているように見えますが、実際には、約束はさまざまな速度で処理されます。バックエンドは別の順序でPromiseを受信する可能性があるため、リモートバックエンドを使用するときにこれを知ることが重要です。
タイムアウトを使用して問題を示す例を次に示します。
Promise.all
const myPromises = [
new Promise((resolve) => setTimeout(() => {resolve('A (slow)'); console.log('A (slow)')}, 1000)),
new Promise((resolve) => setTimeout(() => {resolve('B (slower)'); console.log('B (slower)')}, 2000)),
new Promise((resolve) => setTimeout(() => {resolve('C (fast)'); console.log('C (fast)')}, 10))
];
Promise.all(myPromises).then(console.log)
上記のコードでは、3つの約束(A、B、C)がに与えられていPromise.all
ます。3つのプロミスは異なる速度で実行されます(Cが最も速く、Bが最も遅い)。そのため、console.log
約束のステートメントは次の順序で表示されます。
C (fast)
A (slow)
B (slower)
PromiseがAJAX呼び出しの場合、リモートバックエンドはこれらの値をこの順序で受け取ります。ただし、クライアント側Promise.all
では、myPromises
配列の元の位置に従って結果が順序付けられるようにします。そのため、最終結果は次のようになります。
['A (slow)', 'B (slower)', 'C (fast)']
Promiseの実際の実行も保証する場合は、Promiseキューのような概念が必要になります。以下は、p-queueの使用例です(注意:すべてのPromiseを関数でラップする必要があります)。
シーケンシャルプロミスキュー
const PQueue = require('p-queue');
const queue = new PQueue({concurrency: 1});
// Thunked Promises:
const myPromises = [
() => new Promise((resolve) => setTimeout(() => {
resolve('A (slow)');
console.log('A (slow)');
}, 1000)),
() => new Promise((resolve) => setTimeout(() => {
resolve('B (slower)');
console.log('B (slower)');
}, 2000)),
() => new Promise((resolve) => setTimeout(() => {
resolve('C (fast)');
console.log('C (fast)');
}, 10))
];
queue.addAll(myPromises).then(console.log);
結果
A (slow)
B (slower)
C (fast)
['A (slow)', 'B (slower)', 'C (fast)']