How to Use async/await with a forEach loop in JavaScript

You cannot use “async/await” directly within the callback function of a forEach loop because forEach does not wait for promises to resolve.

If you use async/await inside a forEach, the loop will not wait for the asynchronous operation to complete before moving on to the next iteration. This can lead to unintended behavior if you expect each iteration to complete before the next one starts.

To fix this issue, you can use a “for loop”, “for…of loop”, or “map() with Promise.all()” function to achieve the desired asynchronous behavior.

Method 1: Using a for loop with async/await

The traditional for loop allows you full control over the iteration process, making it easier to use async/await.

async function processItem(item) {
  // Simulate a delay of 1 second using setTimeout and a Promise
  return new Promise((resolve) => {
    setTimeout(() => {
      console.log('Processed item:', item);
      resolve();
    }, 1000);
  });
}

async function processArray(array) {
  for (let i = 0; i < array.length; i++) {
    await processItem(array[i]);
  }
  console.log('All items processed');
}

processArray([11, 18, 19, 21]); 

Output

Processed item: 11
Processed item: 18
Processed item: 19
Processed item: 21
All items processed

Method 2: Using a for…of loop with async/await

The for…of loop is more concise than the traditional for loop and works well with async/await.

async function processItem(item) {
  // Simulate a delay of 1 second using setTimeout and a Promise
  return new Promise((resolve) => {
    setTimeout(() => {
      console.log('Processed item:', item);
      resolve();
    }, 1000);
  });
}

async function processArray(array) {
  for (const item of array) {
    await processItem(item);
  }
  console.log('All items processed');
}

processArray([11, 18, 19, 21]); 

Output

Processed item: 11
Processed item: 18
Processed item: 19
Processed item: 21
All items processed

Method 3: Using the map() with Promise.all()

To process all elements concurrently and then wait for all of them to complete, you can use map() to create an array of promises and then use Promise.all() to wait for all promises to resolve.

async function processItem(item) {
  // Simulate a delay of 1 second using setTimeout and a Promise
  return new Promise((resolve) => {
    setTimeout(() => {
      console.log('Processed item:', item);
      resolve();
    }, 1000);
  });
}

async function processArray(array) {
  await Promise.all(array.map(async (item) => {
    await processItem(item);
  }));
  console.log('All items processed');
}

processArray([11, 18, 19, 21]); 

Output

Processed item: 11
Processed item: 18
Processed item: 19
Processed item: 21
All items processed

That’s it!