JavaScript Async forEach
In today’s post, we’ll look at whether we can use async
in JavaScript’s forEach
loop. What are the alternatives?
Async forEach
in JavaScript
Asynchronous programming is not intended for Array.prototype.forEach
. It is inappropriate for async-await
, just as it was for promises.
const employees = await this.getEmployees();
// BAD
await employees.forEach(async (employee) => {
await giveBonusToEmployee(employee);
});
await sendEmail('All bonuses sent');
Here are some of the problems with this:
- The iterator function’s promises returned are not handled; therefore, it won’t be noticed if one of them makes an error. If there isn’t an
unhandledrejection
listener registered on Node 10, the process will crash! - All bonuses are distributed concurrently rather than sequentially because
forEach
does not wait for each promise to be fulfilled one by one. As a result, the loop ends before all the bonuses have been given out. - As a result, before any of the bonuses have been given out completely,
sendEmail()
sends the email. Perhaps none will be given out; they might all throw errors!
Below is the solution we can implement for this:
- Process each bonus in serial. You may use the
for...of
construction as JavaScript supportsasync-await
.
for (const employee of employees) {
await giveBonusToEmployee(employee);
}
Before moving on to the next bonus, this loop will wait for the previous one to be given out. Although it would be more verbose than we need, you could also use a typical for(...;...;...)
in this situation.
- Process all the bonuses in parallel.
await Promise.all(employees.map(async (employee) => {
await giveBonusToEmployee(employee);
}));
It can be quicker to analyze all the employees simultaneously if the order doesn’t matter. This will begin giving out all of the bonuses at once, but it won’t sendEmail()
until every bonus has been sent.
The for
and while
loops naturally operate with async-await
because they are written in the original function body. However, when you call out to another function, async-await
can only be used if the called function returns a promise and handles that promise.
Because both .reduce()
and .map()
produce a promise or an array of promises we may await
, we can use them.
However, most array methods do not return promises or allow promises to be passed from one call to another, making it impossible to use them asynchronously. As a result, asynchronous code cannot be used inside an array, for example, array.some()
or array.filter()
.
Shraddha is a JavaScript nerd that utilises it for everything from experimenting to assisting individuals and businesses with day-to-day operations and business growth. She is a writer, chef, and computer programmer. As a senior MEAN/MERN stack developer and project manager with more than 4 years of experience in this sector, she now handles multiple projects. She has been producing technical writing for at least a year and a half. She enjoys coming up with fresh, innovative ideas.
LinkedIn