I have a function with an array of promises, that array can have from 1 to X promises.
Those promises enter into the array based on conditionals.
I want to be able to distinguish from which API comes each result, and I can't realise a clean way to do it
let promises = [];
if (false) {
let promise1 = request(toUrl);
promises.push(promise1);
}
if (true) {
let promise2 = request(toUrl);
promises.push(promise2);
}
if (false) {
let promise3 = request(toUrl);
promises.push(promise3);
}
if (true) {
let promise4 = request(toUrl);
promises.push(promise4);
}
try {
let result = await Promise.all(promises);
} catch (error) {
console.log(error);
}
So, if everything goes ok result will be an array of results. Not knowing which one of the conditionals was true, how do I know if result[0] is the result of promise1, promise2 or promise3?
Promise.all() The Promise.all() method takes an iterable of promises as an input, and returns a single Promise that resolves to an array of the results of the input promises. This returned promise will fulfill when all of the input's promises have fulfilled, or if the input iterable contains no promises.
Here, Promise. all() method is the order of the maintained promises. The first promise in the array will get resolved to the first element of the output array, the second promise will be a second element in the output array and so on.
Often Promise. all() is thought of as running in parallel, but this isn't the case. Parallel means that you do many things at the same time on multiple threads. However, Javascript is single threaded with one call stack and one memory heap.
Notice that it's not await that resolves them. Promise. all does not improve performance. It's the "not waiting for the first promise before starting the second task" that improves performance (if done correctly).
You can just add to the response of your request(url)
another information about the promise like
const promise1 = request(url).then(res => ({ res: res, promise: 'promise1' }))
and at the Promise.all()
you will get values of the promises in the above form and can detect which promises were resolved.
Example
const promises = [];
if(true) {
const promise1 = fetch('https://jsonplaceholder.typicode.com/posts/1').then(res => ({ res: res, promise: 'promise1' }));
promises.push(promise1);
}
if(false) {
const promise2 = fetch('https://jsonplaceholder.typicode.com/posts/2').then(res => ({ res: res, promise: 'promise2' }));
promises.push(promise2);
}
Promise.all(promises).then(res => console.log(res));
In my opinion we can simplify the complexity of the problem by using following code -
let promises = [];
let truthyValue = true,
falsyvalue = true;
let [promise1, promise2, promise3, promise4] = await Promise.all([
truthyValue ? request(toUrl) : Promise.resolve({}),
truthyValue ? request(toUrl) : Promise.resolve({}),
falsyValue ? request(toUrl) : Promise.resolve({}),
falsyValue ? request(toUrl) : Promise.resolve({})
]);
// promise1 will be called only when truthyValue is set
if (promise1) {
// do something
}
// promise2 will be called only when truthyValue is set
if (promise2) {
// do something
}
// promise3 will be called only when falsyValue is set
if (promise3) {
// do something
}
// promise4 will be called only when falsyValue is set
if (promise4) {
// do something
}
I used an object map of promises with a name key in order to identify which resolve corresponds to which promise.
const promises = {};
const mapResolveToPromise = res => Object.fromEntries(
Object.entries(promises).map(([key], index) => [key, res[index]])
);
promises.promise1 = fetch('https://jsonplaceholder.typicode.com/posts/1');
promises.promise2 = fetch('https://jsonplaceholder.typicode.com/posts/2');
Promise.all(Object.values(promises))
.then(mapResolveToPromise)
.then(res => {
console.log(res.promise1.url);
console.log(res.promise2.url);
});
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