Get your first promise made.

If I have two promises A and B, only one of them will be successful, how can I get what is successfully completed? I am looking for something similar to Promise.race , but which will return only the first promise that it fulfills. I am using promises from ES6.

+6
source share
4 answers

Invert the polarity of promises, and then you can use Promise.all because it rejects the first rejected promise, which after the inversion corresponds to the first fulfilled promise:

 const invert = p => new Promise((res, rej) => p.then(rej, res)); const firstOf = ps => invert(Promise.all(ps.map(invert))); // Utility routines used only in testing. const wait = ms => new Promise(res => setTimeout(() => res(ms), ms)); const fail = f => Promise.reject(f); const log = p => p.then(v => console.log("pass", v), v => console.log("fail", v)); // Test. log(firstOf([wait(1000), wait(500) ])); log(firstOf([wait(1000), fail("f1")])); log(firstOf([fail("f1"), fail("f2")])); 

This will return the value of the first promise made, or if everything is rejected, an array of reasons for rejection.

+13
source

If you want the first promise to be successfully resolved, and you want to ignore any deviations that were before, 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 errors function firstPromiseResolve(array) { return new Promise(function(resolve, reject) { if (!array || !array.length) { return reject(new Error("array passed to firstPromiseResolve() cannot be empty")); } var errors = new Array(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 reject if (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 this first promise is rejected, it will report a refusal. Thus, he does not do what you asked in your question, which should report the first promise that resolves (even if some refusals have ended before him).

FYI, the Bluebird promise library has both Promise.some() and Promise.any() that can handle this case for you.

+4
source

I had the same question and I tried. You will learn a lot by trying these problems yourself!

  1. The accepted answer is very elegant, but uses Promise.all , which is fun for those who study Promises; also a little hard to follow IMO.
  2. jfriend00 answer is similar to mine, but it has the logic that goes beyond the framework of the Promises, which is the most important here.

I used these nice helper functions present in the accepted answer:

 function firstPromise(promiseL, promiseR) { return new Promise((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); }) }) }) } const wait = ms => new Promise(res => setTimeout(() => res(ms), ms)); const log = 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"))); 

0
source
  //example 1 var promise_A = new Promise(function(resolve, reject) { //  -, , … setTimeout(function(){ return resolve(10); //return reject(new Error('')) },10000) }); var promise_B = new Promise(function(resolve, reject) { //  -, , … setTimeout(function(){ return resolve(100); },2000) }); /* //[100,10] Promise.all([ promise_A,promise_B ]).then(function(results){ console.log(results) }); */ //100 Promise.race([ promise_A,promise_B ]).then(function(results){ console.log(results) }); 
-1
source

Source: https://habr.com/ru/post/1257916/


All Articles