Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Best way to wait for .forEach() to complete

Sometimes I need to wait for a .forEach() method to finish, mostly on 'loader' functions. This is the way I do that:

$q.when(array.forEach(function(item){ 
    //iterate on something 
})).then(function(){ 
    //continue with processing 
});

I can't help but feel that this isn't the best way to wait for a .forEach() to finish. What is the best way to do this?

like image 824
Jaap Weijland Avatar asked Jul 16 '16 01:07

Jaap Weijland


People also ask

Which is the fastest while for forEach () for of?

Correctly used, while is the fastest, as it can have only one check for every iteration, comparing one $i with another $max variable, and no additional calls before loop (except setting $max) or during loop (except $i++; which is inherently done in any loop statement).

Does JS wait for forEach?

All in all, JavaScript forEach function executes code synchronously regardless of using it with or without the async and await keywords, which are meant to run code asynchronously.

Does JavaScript wait for loop to finish?

To use Javascript promises in a for loop, use async / await . This waits for each promiseAction to complete before continuing to the next iteration in the loop.

What is faster map or forEach?

map(function(number){ return number }) console. log(mapNum) //output [2,3,5,7] map() is faster than forEach()


2 Answers

If there is no asynchronous code inside the forEach, forEach is not asynchronous, for example in this code:

array.forEach(function(item){ 
    //iterate on something 
});
alert("Foreach DONE !");

you will see the alert after forEach finished.

Otherwise (You have something asynchronous inside), you can wrap the forEach loop in a Promise:

var bar = new Promise((resolve, reject) => {
    foo.forEach((value, index, array) => {
        console.log(value);
        if (index === array.length -1) resolve();
    });
});

bar.then(() => {
    console.log('All done!');
});

Credit: @rolando-benjamin-vaz-ferreira

like image 172
Ismail RBOUH Avatar answered Oct 17 '22 14:10

Ismail RBOUH


The quickest way to make this work using ES6 would be just to use a for..of loop.

const myAsyncLoopFunction = async (array) => {
  const allAsyncResults = []

  for (const item of array) {
    const asyncResult = await asyncFunction(item)
    allAsyncResults.push(asyncResult)
  }

  return allAsyncResults
}

Or you could loop over all these async requests in parallel using Promise.all() like this:

const myAsyncLoopFunction = async (array) => {
  const promises = array.map(asyncFunction)
  await Promise.all(promises)
  console.log(`All async tasks complete!`)
}
like image 99
Douglas Rosebank Avatar answered Oct 17 '22 14:10

Douglas Rosebank