0

I have the following code that is working fine, and I'm looking to improve the performance even more by running all promises together, instead of running two arrays of promises one after each other.

In the following snippet of the below source code:

    const forms = await Promise.all(formsPromises);
    const responses = await Promise.all(responsesPromises);

Here, I'm running first an array of formsPromises (which themselves run in parallel of each other), and once it's over, I run another array of responsesPromises. I wonder how could I run them all in parallel (responsesPromises shouldn't wait for formsPromises to complete)

I looked into other similar questions but didn't find a proper way of doing so, like there How to do promise.all for array of array of promises?

That's because I still need to keep a reference of all those results, per "type" (form vs response promises) and I don't see how that's possible when using techniques like reduce and alike.

    const formsPromises = []; // Will contain Promises
    const responsesPromises = []; // Will contain Promises
    const results = { // Define initial shape of the results (which is what we should get from the API if there were no results)
      items: [],
      answersCsv: [],
      total_items: 0,
      page_count: 0,
      avg_elapsed_seconds: 0,
    };
    const computedResults = []; // Used to calculate statistic data based on all responses

    // XXX Run all promises in parallel
    map(parameters.form_ids_cleaned, (form_id) => {
      // Fetch the form data, necessary during computing in order to resolve refs for multi choices questions
      formsPromises.push(typeformAPI.forms.get({ uid: form_id }));

      // Fetch the responses for the form
      // XXX This will perform a recursive call under the hood if there are many results and no results limit is defined
      responsesPromises.push(fetchFormResponses({
        parameters,
        queryStringParameters: event.queryStringParameters,
        typeFormApiParameters: {
          ...typeFormApiParameters,
          uid: form_id,
        },
        typeformAPI,
      }));
    });
    // ------ HERE ---------
    const forms = await Promise.all(formsPromises);
    const responses = await Promise.all(responsesPromises);

    map(responses, (response, index) => {
      // Compute results for each set of responses (per form), which will bind CSV-friendly fields and computed statistic data
      computedResults.push(computeResults(response, forms[index]));
    });
Vadorequest
  • 16,593
  • 24
  • 118
  • 215
  • TBH, *How to do promise.all for array of array of promises?* seems to be exactly what you need, I'm inclined to close as a duplicate. Why did you not find the solution there? – Bergi Mar 23 '19 at 14:00
  • I couldn't understand how to keep the reference for each array of promises in a separate variable, as I need them to loop over the results by kind. Examples used in that question did not show me (or I missed it) how to do that, in particular. But Jonas's answer was exactly what I needed. – Vadorequest Mar 23 '19 at 21:35

1 Answers1

3
 const [forms, responses] = await Promise.all([Promise.all(formsPromises), Promise.all(responsesPromises)]);
Jonas Wilms
  • 132,000
  • 20
  • 149
  • 151