How push returned value into array with multiple asynchronous await calls in foreach loop

async await while loop javascript
async push to array
javascript wait for foreach to finish
waiting for promises in a loop
javascript loop through array async
javascript async loop promise
no-await-in-loop
can you await in a for loop

I want to make multiple asynchronous await function calls in a forEach loop and push the returned value into an array. But it returns a promise. How can I store the actual returned value in the array? Thanks for the help.

let table1Assignments = [];
        await groupingTable1Id.forEach(table1Id => {(
             table1Assignments.push(assignmentsDAO.getAssignmentsOfTable(table1Id, date, time)))
        });

getAssignmentsOfTable looks like this:

 async getAssignmentsOfTable(tableId, date = null) {
   let stmt =
      `SELECT * 
       FROM assignment a
       WHERE a.dining_table_id = $1` + (date?' AND a.date = $2':'');
    const params = date?[tableId, date]:[tableId];

    const result = await this.db.query(stmt, params);

    return result.rows.map(row => {
        return new Assignment(
          row.id,
          row.dining_table_id,
          row.guest_group_id,
          row.date,
          row.time
        );
    });
}

I would follow this pattern:

Promise.all([
  groupingTable1Id.map(table1Id => assignmentsDAO.getAssignmentsOfTable(table1Id, date, time))
]).then((table1Assignments) => {
  table1Assignments.forEach(assignment) { process(assignment) });
});

See documentation about JavaScript (ES6) Promise.all here...

Using async/await with a forEach loop, Each of the async callback function calls does return a promise, but you're from several different child refs and then pushing them all into an array and  As you can see the code is very similar to the example that does not return a value. to apply the await keyword directly to your foreach of calling async methods in a foreach loop. This

You can use Promise.all to group your promises under one big promise. It looks like this

const promises = Promise.all(
  // map your IDs to assignment promises
  groupingTable1Id.map(table1Id => assignmentsDAO
    .getAssignmentsOfTable(table1Id, date, time))
);

promises.then(table1Assignments => {
  // Do stuff with assignments
  table1Assignments.forEach(console.log);
});

Making array iteration easy when using async/await, Node.js version 8 is out, and we're finally able to use async/await natively in the server side. Actually, there are many related questions in Stack Overflow. Using a for-of loop instead of forEach() is going to work, but as you can we don'​t need the values returned by map() (an Array of Promises again). If you want to execute await calls in series, use a for-loop (or any loop without a callback). Don’t ever use await with forEach. Use a for-loop (or any loop without a callback) instead. Don’t await inside filter and reduce. Always await an array of promises with map, then filter or reduce accordingly.

Instead of forEach, you can use for of loop, like this:

let table1Assignments = [];
for (const table1Id of groupingTable1Id) {
  table1Assignments.push(await assignmentsDAO.getAssignmentsOfTable(...));
}

Edit: This is not fastest solution in terms of performance because of the sequential execution compared to Promise.all, but I find it clearer.

Dealing with Promises In an Array with async/await - DEV, Promises and async/await is a welcomed addition to the newer versions of return new Promise((resolve) => { setTimeout(() => resolve(2), 2000); The promise resolves to an array of all the values that the each of the promise returns. of array returned from an API call or the likes, so you will have to split  list.map() returns a list of promises, so in result we’ll get the value when everything we ran is resolved. Remember, we must wrap any code that calls await in an async function. See the promises article for more on promises, and the async/await guide.

JavaScript loops - how to handle async/await, How to run async loops in sequence or in parallel? But anonymous function that we use for forEach is synchronous. 2. Process array in sequence. To wait the result we should return back to old-school await func(item); // typo, here you want to call=> delayedLog(item) }) updatedPhotos.push(photo); If you’re trying to loop over a list while using async/await in Node.js (or the browser, for that matter), reaching for the .forEach array function might seem like a natural choice. Let’s say you go that route, fire up your tests or your application, and expect the synchronous-reading magic of async/await to do what it says and actually

Array.prototype.forEach(), the value of the element; the index of the element; the Array object being Elements which are appended to the array after the call to forEach() There is no way to stop or break a forEach() loop other than by let ratings = [5, 4, 5]; let sum = 0; let sumFunction = async function (a, b) { return a + b } ratings. The code calls an asynchronous method, CreateMultipleTasksAsync, which drives the application. Add the following support methods to the project: ProcessURLAsync uses an HttpClient method to download the contents of a website as a byte array. The support method, ProcessURLAsync then displays and returns the length of the array.

JavaScript async and await in loops, I share some gotchas you have to watch out for when you use async Let's say we have an array of fruits we want to get from the fruit basket. Since getNumFruit returns a promise, we can await the resolved value before logging it. to call console.log('End') before the promises in the forEach loop gets  By running this code into node, we can now see: $ node forEach.js $ Done $ 1 $ 2 $ 3. We’re getting closer! Actually, our asyncForEach returns a Promise (since it’s wrapped into an asyncfunction) but we are not waiting for it to be done before logging ‘Done’. Let’s update our example again to wrap our execution into an async method:

Comments
  • This is non-optimal since each iteration needs to wait for the previous one to finish. Marco's answer uses a more efficient approach.
  • True, although if optimization is what you need, you would go for a for loop instead of .map method. But I agree if you you have no issue with each iteration being executed in parallel, Promise.all is faster. But I think my way is clearer and easier to understand.
  • That's comparing apples and oranges. Here you're doing sequential async work. Promise.all parallelises that work. The performance benefits you can get from parallel async work are potentially huge.
  • Yes, that is exactly what I said: if you have no issue with each iteration being executed in parallel, Promise.all is faster
  • I was mostly replying to your although if optimization is what you need, you would go for a for loop instead of .map method line. This is a micro-optimisation. Parallel async work is not though.