Get First Fulfilled Promise
Solution 1:
If you want the first promise that resolves successfully and you want to ignore any rejections that come before that, then you can use something like this:
// returns the result from the first promise that resolves// or rejects if all the promises reject - then return array of rejected errorsfunctionfirstPromiseResolve(array) {
returnnew Promise(function(resolve, reject) {
if (!array || !array.length) {
return reject(newError("array passed to firstPromiseResolve() cannot be empty"));
}
var errors = newArray(array.length);
var errorCntr = 0;
array.forEach(function (p, index) {
// when a promise resolves
Promise.resolve(p).then(function(val) {
// only first one to call resolve will actually do anything
resolve(val);
}, function(err) {
errors[index] = err;
++errorCntr;
// if all promises have rejected, then rejectif (errorCntr === array.length) {
reject(errors);
}
});
});
});
}
I don't see how you can use Promise.race()
for this because it simply reports the first promise to finish and if that first promise rejects, it will report a rejection. So, it is not doing what you asked in your question which is to report the first promise that resolves (even if some rejections finished before it).
FYI, the Bluebird promise library has both Promise.some()
and Promise.any()
which can handle this case for you.
Solution 2:
ES2021 / ES12 - Promise.any
Promise.any
- first fulfilled Promise wins.
const promiseA = Promise.reject();
const promiseB = newPromise((resolve) =>setTimeout(resolve, 100, 'succeed'));
const promises = [promiseA, promiseB];
Promise.race(promises).then((value) =>console.log(value)); // rejected promisePromise.any(promises).then((value) =>console.log(value)); // "succeed"
Notice that any
is ignoring the first rejected promise - promiseA
because promiseB
is being resolved
If all of the given promises are rejected, then the returned promise is rejected.
This is finished proposal and it's scheduled for ES2021 (expected to be released in June 2021)
Solution 3:
I had the same question and gave it a go. You learn a lot by trying these problems yourself!
- The accepted answer is very elegant but uses
Promise.all
which takes the fun for someone learning Promises; also a bit hard to follow imo. jfriend00
's answer is similar to mine but has that logic that goes beyond the Promises fundamentals which is most important here.
I have made use of those nice helper functions present on the accepted answer:
functionfirstPromise(promiseL, promiseR) {
returnnewPromise((resolve, reject) => {
promiseL.then(l => {
resolve(l);
}).catch(error =>null);
promiseR.then(r => {
resolve(r);
}).catch(error =>null);
promiseL.catch(errorL => {
promiseR.catch(errorR => {
reject(errorL + errorR);
})
})
})
}
constwait = ms => newPromise(res =>setTimeout(() =>res(ms), ms));
constlog = p => p.then(v =>console.log("pass", v), v =>console.log("fail", v));
log(firstPromise(wait(1000), wait(500)));
log(firstPromise(wait(1000), Promise.reject("Bar")));
log(firstPromise( Promise.reject("Foo"), wait(500)));
log(firstPromise( Promise.reject("Foo"), Promise.reject("Bar")));
Solution 4:
//example 1var promise_A = newPromise(function(resolve, reject) {
// выполнить что-то, возможно, асинхронно…setTimeout(function(){
returnresolve(10);
//return reject(new Error('ошибка'))
},10000)
});
var promise_B = newPromise(function(resolve, reject) {
// выполнить что-то, возможно, асинхронно…setTimeout(function(){
returnresolve(100);
},2000)
});
/*
//[100,10]
Promise.all([
promise_A,promise_B
]).then(function(results){
console.log(results)
});
*///100Promise.race([
promise_A,promise_B
]).then(function(results){
console.log(results)
});
Post a Comment for "Get First Fulfilled Promise"