Як уже було сказано в попередніх відповідях, Promise.all
агрегується всі розв’язані значення масивом, що відповідає порядку введення вихідних Обіцянь (див. Агрегативні обіцянки ).
Однак я хотів би зазначити, що замовлення зберігається лише на стороні клієнта!
Для розробника схоже, що Обіцянки виконувались в порядку, але насправді Обіцяння обробляються з різною швидкістю. Це важливо знати, коли ви працюєте з віддаленим сервісом, тому що він може отримати ваші обіцянки в іншому порядку.
Ось приклад, який демонструє проблему за допомогою таймаутів:
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)
У наведеному вище коді дано три обіцянки (A, B, C) Promise.all
. Три обіцянки виконують з різною швидкістю (C - найшвидший, а B - найповільніший). Ось чому console.log
заяви Обіцянь відображаються в такому порядку:
C (fast)
A (slow)
B (slower)
Якщо Обіцянки - це дзвінки AJAX, то віддалений сервер отримуватиме ці значення в цьому порядку. Але з боку клієнта Promise.all
гарантує, що результати впорядковані відповідно до вихідних позицій myPromises
масиву. Ось чому кінцевий результат:
['A (slow)', 'B (slower)', 'C (fast)']
Якщо ви хочете гарантувати фактичне виконання ваших Обіцянок, вам знадобиться така концепція, як черга обіцянки. Ось приклад використання p-черги (будьте обережні, вам потрібно ввести всі обіцянки у функції):
Послідовна черга обіцянок
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)']