JavaScript Async forEach

Shraddha Paghdar Nov 28, 2022
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:

  1. 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!
  2. 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.
  3. 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:

  1. Process each bonus in serial. You may use the for...of construction as JavaScript supports async-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.

  1. 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 Paghdar avatar Shraddha Paghdar avatar

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

Related Article - JavaScript Async

Related Article - JavaScript Loop