Reputation: 10627
Currently, this code print out a zero, because the first promise in the array resolves immediately.
const promises = [];
const promiser = (number) => new Promise((resolve, reject) => window.setTimeout(() => resolve(number), number * 100));
for (let index = 0; index < 10; index++) {
const promise = promiser(index);
promises.push(promise);
}
Promise.race(promises).then(r => console.debug(r));
I'm looking to make it so that once the quickest promise resolves, it is removed from the promises
array and a new Promise.race
call is made with the remaining promises, repeating until no promise is left.
Since Promise.race
returns the result of the promise, not the resolved promise itself, though, I am unable to identify which promise was it that resolved and I do not know which one to remove from the array. Is there a way to know this? I suppose I could return a complex object with some sort of a correlation key and the result, but that seems weird. I was hoping second parameter of the Promise.race
callback would be index of the promise, but that's not the case and it doesn't make sense either since the then
is just a then
of another promise, so how would it know that it should return some index anyway. Can you think of a better way?
Also, I run all the promises with the first race
, but that shouldn't be a problem for subsequent race
s, right? In case another promise resolved in the meantime before the subsequent race
call was made, it should just return it, no problem, correct? And if multiple promises did resolve in the meantime, it would just return the first (in array order or in resolution order?) and then the next race
would return the second and so on… Right?
BTW I also though I could walk the array and remove promises that have isResolved
, but that's not a real thing. Even if it was, though, this would completely break for the case where multiple promises resolve between the calls to race
.
Upvotes: 3
Views: 1365
Reputation: 20159
I'm looking to make it so that once the quickest promise resolves, it is removed from the
promises
array and a newPromise.race
call is made with the remaining promises, repeating until no promise is left.
Why do you want to use Promise.race
if you eventually want to handle all promises? Can't you simply process every promise as soon as it resolves, and then wait until all promises have been processed?
const promises = [];
const promiser = (number) => new Promise((resolve, reject) => window.setTimeout(() => resolve(number), number * 100));
for (let index = 0; index < 10; index++) {
const promise = promiser(index)
.then(r => process(r)); // process every promise individually
promises.push(promise);
}
Promise.all(promises) // wait for all promises to be processed
.then(r => console.debug('all done!'));
Or is process
also asynchronous, and you need to ensure that only one promise is getting processed at a time?
Upvotes: 5
Reputation: 19581
You can return an identifier to the promises
const promises = [];
const promiser = (number, id) => new Promise((resolve, reject) => window.setTimeout(() => resolve({ number, id }), number * 100));
for (let index = 0; index < 10; index++) {
const promise = promiser(index, "id_" + index);
promises.push(promise);
}
Promise.race(promises).then(r => console.debug(r.id));
Anyway if you are working with a promise library such as bluebird you can find some utility that can help you structure your code better ( like Promise.reduce
or Promise.any
)
Upvotes: 1