Come già indicato nelle risposte precedenti, Promise.all
aggrega tutti i valori risolti con un array corrispondente all'ordine di input delle Promesse originali (vedere Aggregating Promises ).
Tuttavia, vorrei sottolineare che l'ordine è conservato solo dal lato client!
Per lo sviluppatore sembra che le Promesse siano state rispettate nell'ordine, ma in realtà le Promesse vengono elaborate a velocità diverse. Questo è importante sapere quando lavori con un back-end remoto perché il back-end potrebbe ricevere le tue promesse in un ordine diverso.
Ecco un esempio che dimostra il problema utilizzando i timeout:
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)
Nel codice mostrato sopra, vengono date tre Promesse (A, B, C) Promise.all
. Le tre promesse vengono eseguite a velocità diverse (C è la più veloce e B la più lenta). Ecco perché le console.log
dichiarazioni delle Promesse si presentano in questo ordine:
C (fast)
A (slow)
B (slower)
Se le promesse sono chiamate AJAX, un back-end remoto riceverà questi valori in questo ordine. Ma dal lato client Promise.all
garantisce che i risultati siano ordinati in base alle posizioni originali myPromises
dell'array. Ecco perché il risultato finale è:
['A (slow)', 'B (slower)', 'C (fast)']
Se vuoi garantire anche l'effettiva esecuzione delle tue Promesse, allora avrai bisogno di un concetto come una coda di Promessa. Ecco un esempio usando la coda-p (attenzione, è necessario racchiudere tutte le promesse nelle funzioni):
Coda di promessa sequenziale
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);
Risultato
A (slow)
B (slower)
C (fast)
['A (slow)', 'B (slower)', 'C (fast)']