I'm currently working on something where I fire out three promises in an array. At the moment it looks something like this
var a = await Promise.all([Promise1(), Promise2(), Promise3()]);
Now all of those promises will either return true or false. But at the moment I'm waiting for all of them to be finished and I could go on as soon as one of them returns true.
I thought of ways to accomplish that but all seem kind of ugly. How would you solve this task?
The keyword await is used to wait for a Promise. It can only be used inside an async function. This keyword makes JavaScript wait until that promise settles and returns its result.
race() , which returns the first settled value (either fulfillment or rejection), this method returns the first fulfilled value.
You can use Promise. all (spec, MDN) for that: It accepts a bunch of individual promises and gives you back a single promise that is resolved when all of the ones you gave it are resolved, or rejected when any of them is rejected.
Using Promise.allPromise.all waits for all fulfillments (or the first rejection).
You can implement that combining Promise.race
and Promise.all
:
function firstTrue(promises) { const newPromises = promises.map(p => new Promise( (resolve, reject) => p.then(v => v && resolve(true), reject) )); newPromises.push(Promise.all(promises).then(() => false)); return Promise.race(newPromises); }
Test for above code:
function firstTrue(promises) { const newPromises = promises.map(p => new Promise( (resolve, reject) => p.then(v => v && resolve(true), reject) )); newPromises.push(Promise.all(promises).then(() => false)); return Promise.race(newPromises); } var test = values => firstTrue( values.map((v) => new Promise((resolve) => { setTimeout(() => resolve(v), Math.round(Math.random() * 1000)); })) ).then((ret) => console.log(values, ret)); test([true, true, true]); test([false, false, false]); test([true, false, false]); test([false, true, false]); test([false, false, true]);
You can create a new promise that resolves as soon as any given promise resolves to true
like this:
function promiseRaceTrue(promises) { return new Promise(function(resolve, reject) { promises.forEach(promise => promise.then(val => val === true && resolve()) // TODO handle resolve with value of "false"? // TODO handle rejection? ); // TODO handle all resolved as "false"? }); } var a = await promiseRaceTrue([Promise1(), Promise2(), Promise3()]);
It behaves similar to Promise.race
but only resolves if one of the given promises resolves with the value true
instead of resolving as soon as any of the given promises either resolves or rejects.
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