Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Conditional/dynamic array promise all

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?

like image 868
Lucas Janon Avatar asked Nov 28 '17 05:11

Lucas Janon


People also ask

What does promise all () do?

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.

Does promise all resolve promises in order?

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.

Is promise all sequential or parallel?

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.

Does promise all improve performance?

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).


3 Answers

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));
like image 96
Suren Srapyan Avatar answered Oct 26 '22 01:10

Suren Srapyan


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
 }
like image 4
Arjun Londhey Avatar answered Oct 26 '22 00:10

Arjun Londhey


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);
  });
like image 2
Callistino Avatar answered Oct 26 '22 01:10

Callistino