skip to Main Content

I am using Promise.all to handle multiple promises simultaneously, but I also need to run a function for each resolved promise. The issue I’m facing is that if I pass the function directly to the .then() of the promise, it gets executed immediately, not waiting for the Promise.all to trigger it. How can I achieve executing a function for each resolved promise while still using Promise.all? I’m also need get the progress of this Promise.all

async function fetchData(url) {
/***
I want to append a callbackResolve for this fetch, 
but if I use .then() it execute the function and not the Promise.all
**/

  return await fetch(url);
}

const urls = [
  'https://api.example.com/data1',
  'https://api.example.com/data2',
  'https://api.example.com/data3'
];


Promise.all(urls.map(fetchData))

2

Answers


  1. If all promises fulfil, Promise.all returns a promise that resolves with an array of values –the resolution values of the original promises. So you could just iterate that array and perform the extra logic on them.

    Like this:

    function fetchData(url) {
      return fetch(url);
    }
    
    const urls = [
      'https://api.example.com/data1',
      'https://api.example.com/data2',
      'https://api.example.com/data3'
    ];
    
    const promises = urls.map(fetchData);
    Promise.all(promises).then(arr => {
        arr.forEach(callbackResolve);
    });
    

    To monitor the progress, you can use individual .then() calls on the original promises. For example, complete the above code like this:

    function fetchData(url) {
      return fetch(url);
    }
    
    const urls = [
      'https://api.example.com/data1',
      'https://api.example.com/data2',
      'https://api.example.com/data3'
    ];
    
    const promises = urls.map(fetchData);
    
    let resolveProgress = 0;
    for (const promise of promises) {
        promise.then(() => {
            resolveProgres++;
            console.log("Progress:", 
                        ((resolveProgress / promises.length) * 100).toFixed(2) + "%"
                       );
        });
    }
    
    Promise.all(promises).then(arr => {
        arr.forEach(callbackResolve);
    });
    
    Login or Signup to reply.
  2. Since you need to run the function for each resolved promise, call it after fetchData() completes for each input:

    Promise.all(urls.map(async (url) => {
      const result = await fetchData(url);
      await callbackResolve(url, result);
      await trackProgress(url);
    
      return result;
    }))
    

    Running any processing that is specific to one URL on the value returned by Promise.all() is incorrect design. It is cumbersome and makes the code difficult to read and understand.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search