I have an array with X promises and I need to return them in order of their setTimeout
.
For example. if P1
has timeout set for 3000ms, and P2
resolves after 1000ms, we want to first return P2 and then P1. The code looks like this:
const P1 = new Promise((resolve) => {
setTimeout(() => resolve('R1'), 3000);
});
const P2 = new Promise((resolve) => {
setTimeout(() => resolve('R2'), 5000);
});
const P3 = new Promise((resolve) => {
setTimeout(() => resolve('R3'), 1000);
});
async function fetchInitialData(arr) {
return Promise.all(arr);
}
fetchInitialData([P1, P2, P3])
.then((data) => {
console.log('result', data);
});
In this scenario we’re returning promises but they’re not sorted by resolve time, it would return R1, R2, R3
.
We want to return them by their resolve time, so in this case: R3, R1, R2
.
2
Answers
Assuming I understand the example, it sounds like you want the
fetchInitialData
to indeed wait for all of the Promises to complete, but internally to append the result of eachPromise
to the result as it completes.Instead of returning
Promise.all
, you can awaitPromise.all
after appending a.then()
to each Promise, which appends its result to an array. For example:Right, that’s a guarantee
Promise.all
provides: The array it fulfills its promise with is the fulfillment values of the input promises, in input order.You could write your own function that instead builds the array in order of fulfillment, for instance:
There, we put the promises in the array as they’re fulfilled, returning the array when they’ve all been fulfilled (or when any of them is rejected, which will reject the promise our function returns).
Live example:
The
Array.from(promises, (p) => ___)
is so the function supports any iterable of promises, rather than just arrays. I did that to make it consistent withPromise.all
,Promise.allSettled
, etc. work.