Reputation: 10372
In TypeScript I'm creating about 100 Promise
instances that may all be resolved or rejected. But I only need to wait for 5 of them to be resolved, then the rest must be canceled (if possible) as they do work that is not needed anymore. If canceling is not possible rejecting the rest would also be fine.
How can this be done?
Upvotes: 0
Views: 58
Reputation: 10377
I believe this function should do it.
export function execSome<T>(arr: Promise<T>[], limit:number) {
let boxedLimit = Math.min(limit, arr.length);
let results :T[] = [];
return new Promise((resolve, reject) => {
function onComplete(result:T) {
if (results.length === boxedLimit - 1) {
resolve(results.concat([result]));
} else {
results.push(result);
}
}
arr.forEach(promise => promise.then(onComplete).catch(reject));
})
}
This does assume that your promises all return the same type, but you can easily pass in a union type, any, or void depending on your needs.
The basic idea is for each promise to add to an array they all have access to. If the current promise is going to satisfy the requirements, go ahead and resolve the overall promise using the common results array. We need the boxedLimit
in case you pass in a number. You can use this by passing in an array of 100 promises with 5 as the limit.
To my knowledge there is no feasible way of canceling an ES6 promise so I didn't bother.
You may feel that the onComplete function is structured a bit strangely. When working with async code I prefer there to be only one code path that modifies shared state.
Upvotes: 2