repost: async / await in forEach loop 🤯. Hey! I recently was working on a… | by Nick Graffis | Medium
Hey! I recently was working on a project that had me looping through an array of table names, and wanted to see if each table existed in a MySQL database. Create one if it didn’t exist, then log something.
For this article I’m going to use a different promised based function, instead of the MySQL query, for simplicity sake.
We will use this function in our loop:
1 | const waitFor = (ms) => new Promise((res) => setTimeout(res, ms)); |
So the first thing I tried was:
1 | [10, 2, 3].forEach(async (num) => { |
Seems to make sense, but in reality
1 | $ Done$ 2$ 3$ 10 |
If we take a look at the polyfill for forEach() we get a better idea of what is happening: Array.prototype.forEach() — JavaScript | MDN
Basically it uses a while loop that calls the callback for each entry, but it doesn’t wait for the previous entry to finish.
So we need to create our own asyncForEach():
1 | Array.prototype.asyncForEach = async function (callback) { |
With this new tool we try again:
1 | [10, 2, 3].asyncForEach(async (num) => { |
And we get:
1 | $ Done |
Closer! The asyncForEach() is working great! waiting the 10ms for iteration 0 to finish, before going on to iteration 1.
To get it all to work as expected we can just wrap our execution into an async function:
1 | const go = async () => { |
And then in response:
1 | $ 10 |
👏 And it works!