Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is Array.forEach asynchronous?

Tags:

javascript

According to JavaScript, Node.js: is Array.forEach asynchronous?, Array.forEach is synchronous. However, for my code below:

function wait5() {
    return new Promise(resolve => 
    setTimeout(resolve, 5000));
}

async function main() {
   console.log("Start");
   [1,2].forEach(async (e) => {
      const d = await wait5().then(()=> console.log("5s later") )
   })
   console.log("This should come last!");
}

main();

The output is:

Start
This should come last!
5s later
5s later

with the two "5s later" coming out in rapid succession.

Why is this the case?

If I use a normal for loop:

async function main() {
   console.log("Start");
   for (let i=0;i<2;i++) {
      const d = await wait5().then(()=> console.log("5s later") )
   }
   console.log("This should come last!");
}

then the result is what I wanted:

Start
5s later
5s later
This should come last!
like image 553
Old Geezer Avatar asked Aug 30 '18 16:08

Old Geezer


People also ask

Is array forEach synchronous?

Note: forEach expects a synchronous function. forEach does not wait for promises. Make sure you are aware of the implications while using promises (or async functions) as forEach callback.

Is JS array forEach async?

Array. prototype. forEach is not designed for asynchronous code. (It was not suitable for promises, and it is not suitable for async-await.)

Does forEach run async?

forEach() method to run asynchronous code. Programmers use the forEach method to loop through each of the elements of an array to execute the same process. Unfortunately, the forEach method wasn't meant to execute asynchronous callback functions, even though it is possible to use the keywords async and await with it.

Is angular forEach asynchronous?

forEach method only accepts a synchronous function, and therefore is NOT compatible with the async/await syntax. Instead, you can use the for … of iterator as per below which is compatible with the async/await syntax. function waitForTwoSecs(i) { return new Promise(resolve => { setTimeout(() => { console.


2 Answers

forEach is synchronous. Your particular callback function, however, is not. So forEach synchronously calls your function, which starts its work, once for each entry in the array. Later, the work that started finishes asynchronously, long after forEach has returned.

The issue is that your callback is async, not that forEach is asynchronous.

In general, when you're using an API like forEach that doesn't do anything with the return value (or doesn't expect a promise as a return value), either:

  1. Don't pass it an async function, or

  2. Ensure that you handle errors within the function itself

Otherwise, you'll get unhandled errors if something goes wrong in the function.

Or of course:

  1. Use a try/catch block within the async function to catch and handle/report errors within the function itself.
like image 95
T.J. Crowder Avatar answered Oct 20 '22 19:10

T.J. Crowder


It looks like you're declaring an async function inside of a caller that really doesn't care for that sort of thing, forEach. Declaring a function async makes it promise-like, but that promise is only useful if acted on.

If you need a promise-aware forEach, that's something you could implement, though Promise.each in libraries like Bluebird already do that.

like image 40
tadman Avatar answered Oct 20 '22 19:10

tadman