Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

passing async functions to promise.all()

I know promise.all() expects an array of promises.

But, is it possible to do something like below? If no, please suggest a workaround.

It's not recommended to use await inside for loop. That's why I am pushing in an array and doing promise.all() on that.

var functionArray = [];
for (let i = 0; i < jobs.length; i += 1) {
  ...
  if (params.origins !== '' && params.destinations !== '') {
    functionArray.push(async function() {
      response = await getDistance(params.origins, params.destinations);
      if (response.error) {
        // handle error
        return null
      } else {
        distances = response.data.rows[0].elements.map((el, index) => {
          el.emp_id = empIdOrder[index];
          return el;
        });
        sortedDistances = sortDistance(distances);
        return formatDataForInsert(jobs[i].job_id, sortedDistances);
      }
    });
  }
}
var dataToBeinserted = await Promise.all(functionArray); // return an array with results

It doesn't work as expected.

await Promise.all(functionArray); always return [ [AsyncFunction], [AsyncFunction] ].

Shouldn't it be resolved instead?

like image 634
8bitIcon Avatar asked Aug 31 '25 10:08

8bitIcon


1 Answers

The first problem is that Promise.all accepts an array of promises, not an array of functions - your current code won't work.

The main issue is that you're only conditionally using the result of the asynchronous operation. You can chain .then onto a Promise to make the Promise resolve to the result of the .then, rather than its initial resolve value. That is:

Promise.resolve(2)
  .then(res => res + 4)

results in a Promise that resolves to 6.

Using this logic, you can push a Promise to the array which, in its then, conditionally works with the result (distances = response.data...) and returns the final value, or doesn't return anything. At the end, call Promise.all on the array of Promises, and filter by boolean:

const promises = [];
for (let i = 0; i < jobs.length; i += 1) {
  if (params.origins !== '' && params.destinations !== '') {
    promises.push(
      getDistance(params.origins, params.destinations)
        .then((response) => {
          if (response.error) {
            // handle error
            return null
          } else {
            const distances = response.data.rows[0].elements.map((el, index) => {
              el.emp_id = empIdOrder[index];
              return el;
            });
            const sortedDistances = sortDistance(distances);
            return formatDataForInsert(jobs[i].job_id, sortedDistances);
          }
      })
    );
    }
}
const results = await Promise.all(promises)
  .filter(Boolean); // filter out failures

var dataToBeinserted = await Promise.all(functionArray); // return an array with results
like image 138
CertainPerformance Avatar answered Sep 03 '25 01:09

CertainPerformance