Async/Await and the forEach Pit of Despair
Tags: javascript
Published: 2018-09-13 17:44:29

---
title: Async/Await and the forEach Pit of Despair
published: true
description: 
tags: javascript
---

The JavaScript VM is like a 4 year-old on a sugar high; screaming through your code with no pants on and just executing everything at all once while it draws on your wall with a Sharpie.

Async/Await is like that same 4 year-old taking a nap. Your code is just there, like a perfect angel, doing exactly what you want and you wonder how you could ever love anything so much. Your heart might burst with pride. And you probably need to get out more because we're talking about programming here.

But async/await is not all finger-painting and "first day of Kindergarten". It's got some weirdo edge cases that can make you wonder if you have made a huge mistake by ever deciding to even have JavaScripts. Stop looking at me like that. If you're a parent, you know exactly what I'm talking about.

I ran into one of these strange edge cases on a large project and the complexity of the code made it really hard to debug. That, and I'm not terribly smart to begin with so it was kind of the perfect storm.

## Async/Await Basics

Just to ensure we're all playing our Recorders to the same version of "Hot Crossed Buns", let's look at a simple async/await example.

{% codepen https://codepen.io/burkeholland/pen/GXOBoG %}

Axios returns a Promise, but we can await that Promise so we don't have to deal with any more socially acceptable callbacks.

This is all well and good, but what if we wanted to do an async call inside that `forEach` loop? Easy, just mark the callback as `async` and go about your bizness.

{% codepen https://codepen.io/burkeholland/pen/MqrwWX %}

This works. Or at least it looks like it does. What's the problem here? The problem is that this loop is not executing items in order. Don't believe me? Watch what happens when we throw the index into the loop…

{% codepen https://codepen.io/burkeholland/pen/pOpJyV %}

Chaos. That's what happens. Like a heard of 4-year old's right about nap time.

Why is this happening? Isn't forEach supposed to be a synchronous operation?

Yes. But we are passing in an async function, which tells the VM that it can execute these things however it wants and "however it wants" is "watching the world burn".

This is no good. This is not the solution to anything. Even worse is that this is incredibly hard to debug if you put a lot of misplaced faith in `forEach`. I should know. Async/await is basically negating an extremely important aspect of the built-in array loop.

So how do we fix this? The fix is to go to a `for of` loop.

{% codepen https://codepen.io/burkeholland/pen/pOpJNK %}

And that's what we wanted all along. 

Now I'm not the first person to write about this. The internet is littered with posts about how async/await changes `forEach`. There are also plenty of people saying not to use `forEach` because it's "slower", or something like that. I don't know. I didn't actually read the articles.

I'm not going to recommend that you do or don't use `forEach`, it definitely has it's place. Just remember that when you are doing async/await inside of a `forEach` loop, you are doing it wrong. And don't worry - you'll know you are doing it wrong because it won't work properly and that psychotic toddler of a JavaScript VM will turn your life upside down.

Further Reading: [Moving from Callbacks to Promises and Async/Await](https://www.zeolearn.com/magazine/javascript-moving-from-callbacks-to-promises-and-async-await)