Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to Wait on Async function inside array.forEach in Javascript

I am trying to make an async request within foreach to fetch data in order user it later but its not working for me.

I know Array.Foreach is a synchronous function so I even tried $.when.done but still it does not wait until it finish.

I could have used callback if it was a single value but its an array . Is there a better way to handle this by callback to achieve waiting on async request before moving next?

browseItems.forEach((browseItem: any) => {

   AsynchFunction();

   cosole.log("Step 2")  
}
function AsynchFunction(){
   console.log("Step 1")
}

I am trying to get an output like

Step 1

Step 2

like image 288
Govind Kalyankar Avatar asked Sep 04 '15 03:09

Govind Kalyankar


People also ask

Can async await be used inside forEach?

forEach is not designed for asynchronous code. (It was not suitable for promises, and it is not suitable for async-await.) For example, the following forEach loop might not do what it appears to do: const players = await this.

How do you wait for asynchronous function?

async and await Inside an async function, you can use the await keyword before a call to a function that returns a promise. This makes the code wait at that point until the promise is settled, at which point the fulfilled value of the promise is treated as a return value, or the rejected value is thrown.

Does JavaScript wait for async function to finish?

JavaScript is asynchronous in nature and does not wait for the execution of code. Therefore, it is a challenging task to wait for a piece of code before executing another piece. In this way, users prioritize the specified functions that execute first, while others are in the waiting queue.

How do I use async await inside for loop?

You need to place the loop in an async function, then you can use await and the loop stops the iteration until the promise we're awaiting resolves. You could also use while or do.. while or for loops too with this same structure. But you can't await with Array.


2 Answers

Building on @basarat's answer, I found that this works quite well if you are using the async/await feature in TypeScript (as of TS 1.7 requiring ES6 target):

async function processData(data: any[]) {
  const promises = data.map(async (item) => {
    await doSomeAsyncStuff(item);
    //you can do other stuff with the `item` here
  });
  await Promise.all(promises);

  //you can continue with other code here that will execute after all the async code completes
}

async function doSomeAsyncStuff(value) {
  return new Promise((resolve, reject) => {
    //call some async library or do a setTimeout and resolve/reject the promise
  });
}

Update: async and await are now available for TypeScript code targeting ES5 as well in the master branch of TypeScript, soon to be released as TypeScript 2.1. You can install it today using npm install --save-dev typescript@next

Update: This feature is available for all ES targets in the current version of TypeScript. The one caveat I have noticed is that if you are targeting ES5 or ES3, you will need to provide a Promise polyfill or the code will fail on older browsers.

like image 56
Joe Skeen Avatar answered Oct 24 '22 01:10

Joe Skeen


Is there a better way to handle this by callback to achieve waiting on async req before moving next

If you are using promises you can use a function like Promise.all:

var promises = browseItems.map((browseItem: any) => AsynchFunction());
Promise.all(promises).then((values)=>{});
like image 20
basarat Avatar answered Oct 24 '22 01:10

basarat