var p1 = new Promise((resolve, reject) => {
setTimeout(resolve, 1000, 'one');
});
var p2 = new Promise((resolve, reject) => {
setTimeout(resolve, 2000, 'two');
});
var p3 = new Promise((resolve, reject) => {
setTimeout(resolve, 3000, 'three');
});
Promise.all([p1,p2,p3]).then(values => {
console.log(values);
}, reason => {
console.log(reason)
});
How can i wait for 2 promises to get completed ? Promise.race() wait for one promise to get completed.
I have n number of promises, what i want to achieve is wait for first k number of promises to get resolved and than trigger some event. assume k < n
I am sure that k number of promise will be successfully resolved out of n numbers of promise given
(Note: Bluebird has a built-in helper function that serves precisely this purpose and has more or less the same behavior as my waitForN
method below, so that option is always available)
I don't believe ES6 promises have an elegant built-in way to do this, but you could define the following relatively short now somewhat long helper function to take care of this.
Edit: Added an additional helper function that includes the indices of the successful promises in the result.
Edit: Updated to reject if the number of rejections reaches the point where successful resolution would be impossible.
Edit: Updated to more gracefully work with promises
if it is iterable and check edge cases where the result should immediately resolve (e.g. if n === 0
)
function waitForN(n, promises) {
let resolved = [];
let failCount = 0;
let pCount = 0;
return new Promise((resolve, reject) => {
const checkSuccess = () => {
if (resolved.length >= n) { resolve(resolved); }
};
const checkFailure = () => {
if (failCount + n > pCount) {
reject(new Error(`Impossible to resolve successfully. n = ${n}, promise count = ${pCount}, failure count = ${failCount}`));
}
};
for (let p of promises) {
pCount += 1;
Promise.resolve(p).then(r => {
if (resolved.length < n) { resolved.push(r); }
checkSuccess();
}, () => {
failCount += 1;
checkFailure();
});
}
checkFailure();
checkSuccess();
});
}
const waitForNWithIndices = (n, promises) =>
waitForN(n, promises.map((p, index) =>
Promise.resolve(p).then(result => ({ index, result }))
));
var p1 = new Promise((resolve, reject) => {
setTimeout(resolve, 1000, 'one');
});
var p2 = new Promise((resolve, reject) => {
setTimeout(resolve, 2000, 'two');
});
var p3 = new Promise((resolve, reject) => {
setTimeout(resolve, 3000, 'three');
});
var p4 = new Promise((resolve, reject) => {
setTimeout(resolve, 1500, 'four');
});
waitForN(2, [p1,p2,p3,p4]).then(values => {
console.log(values);
}, reason => {
console.log(reason)
});
waitForNWithIndices(2, [p1,p2,p3,p4]).then(values => {
console.log(values);
}, reason => {
console.log(reason)
});
You could use a higher order function to bake in the n
then run all promises waiting for n
to finish
var p1 = new Promise((resolve, reject) => {
setTimeout(resolve, 1000, 'one');
});
var p2 = new Promise((resolve, reject) => {
setTimeout(resolve, 2000, 'two');
});
var p3 = new Promise((resolve, reject) => {
setTimeout(resolve, 3000, 'three');
});
const raceN = n => (...promises) => {
const resolved = []
return new Promise((res, rej) =>
promises.forEach(promise =>
promise.then(x => {
resolved.push(x)
if (resolved.length === n)
res(resolved)
})
.catch(rej)
)
)
}
const race2 = raceN(2)
race2(p1, p2, p3)
.then(results => console.log(results))
race2(Promise.resolve('resolved'), Promise.reject('rejected'))
.then(results => console.log(results))
.catch(reason => console.log(reason))
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With