DEV Community

Alaa Ezz Eldin
Alaa Ezz Eldin

Posted on

Async Loops in JavaScript: for...of vs forEach

JavaScript’s async capabilities are pretty cool 😎, but choosing the right loop to handle those async tasks can make a big difference. Let’s break down the difference between for...of and forEach with a splash of fun 🎉

1. for...of Loop with Async Functions
Imagine the for...of loop as your super-diligent friend who waits patiently for you to finish one task before starting the next. It’s like waiting for your coffee to brew before you start your next task.

for (const item of items) {
  await doSomethingAsync(item);
}
Enter fullscreen mode Exit fullscreen mode

Suppose you have an array of tasks that each return a resolved promise with a delay:

function doSomethingAsync(item) {
  return new Promise((resolve) => {
    setTimeout(() => resolve(`Processed ${item}`), 1000);
  });
}

async function processItemsSequentially(items) {
  for (const item of items) {
    try {
      const result = await doSomethingAsync(item);
      console.log(result);
    } catch (error) {
      console.error(`Oops! Error with ${item}:`, error);
    }
  }
}

const items = ['Task 1', 'Task 2', 'Task 3'];
processItemsSequentially(items);
Enter fullscreen mode Exit fullscreen mode

processItemsSequentially waits for each doSomethingAsync call to complete before moving on to the next item.

Why You’ll Love It:

🕰️ Patience: It waits for each async task to finish before moving on. It’s all about that orderly life.

🚨 Error Handling: You can easily catch and handle errors within the loop.

🔥 Perfect For: When you need things done in order – like cooking a meal where you can’t bake the cake before mixing the batter XD.


2. forEach with Async Functions
On the flip side, forEach is like a bunch of friends who all start their tasks at the same time. They’re excited and want to finish as quickly as possible. They don’t care if one person finishes before the others; they just go for it!

items.forEach(async (item) => {
  await doSomethingAsync(item);
});
Enter fullscreen mode Exit fullscreen mode

Let’s use the same doSomethingAsync function but with forEach:

async function processItemsConcurrently(items) {
  items.forEach(async (item) => {
    try {
      const result = await doSomethingAsync(item);
      console.log(result);
    } catch (error) {
      console.error(`Whoops! Issue with ${item}:`, error);
    }
  });
}

const items = ['Task A', 'Task B', 'Task C'];
processItemsConcurrently(items);
Enter fullscreen mode Exit fullscreen mode

processItemsConcurrently starts all the doSomethingAsync calls simultaneously, so all tasks run in parallel.

Why It’s Fun:

🏃‍♂️🏃‍♀️ Parallel Execution: All tasks start at once, which can be super fast but a bit chaotic.

✂️ Simpler Syntax: Often shorter and more concise than for...of.

🔥 Perfect For: When tasks don’t depend on each other and can be performed independently, like fetching data from multiple APIs.

Remember:
for...of is your orderly friend who waits their turn.
forEach is all about jumping in at the same time and getting things done fast.

for...of lets you catch errors one by one, which is neat and tidy.
forEach makes you handle errors on the fly, like juggling multiple balls.

for...of might be a tad slower, but it’s neat and orderly.
forEach can be faster if you’re cool with the chaos and tasks don’t overlap.

Choose the loop that fits your needs based on whether you need order and patience or speed and excitement! 🚀🚀

Top comments (0)