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!
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.
Array. prototype. forEach is not designed for asynchronous code. (It was not suitable for promises, and it is not suitable for async-await.)
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.
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.
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:
Don't pass it an async
function, or
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:
try
/catch
block within the async
function to catch and handle/report errors within the function itself.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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With