Search code examples
javascriptes6-promise

How to destructure results of a dynamic number of async calls with Promise.all


I need to make an unknown number of async calls in parallel via Promise.all. Something similar to this:

let externalCalls = [call1()];
if (someCondition1) {
  externalCalls.push(call2());
}
if (someCondition2) {
  externalCalls.push(call3());
}

Then externalCalls will be passed to Promise.all so they can be run in parallel.

Ideally, I'd like to use destructuring of the results so that I can refer to results by name, i.e.

const [call1, call2, call3] = await Promise.all(externalCalls);

I know call1 will always be there, but I don't know if call2 or call3 will be there. So I'd like to define the const result of calling await Promise.all dynamically to have the correct properties, Is this possible? Or am I stuck having a generic results array of unknown length, and then having to inspect each item in the results to see which call produced it?


Solution

  • On the one hand, you already know which calls were .push()ed to externalCalls, based on someCondition1, etc.

    But perhaps it's better to build externalCalls in a different way so it always has the same length:

    const conditions = [true, someCondition1, etc]
    const calls = [call1, call2, etc]
    const externalCalls = conditions.map(
      (c, i) => c ? calls[i]() : Promise.resolve(null))
    const [result1, result2, etc] = await Promise.all(externalCalls)