Executing arrays of async/await JavaScript functions in series vs. concurrently

When dealing with an array of async/await functions (which are Promises), it can be tricky to figure out how to execute them all in series (one-at-a-time) and how to call them in concurrently (not one-at-a-time, executed during overlapping time periods).

Maybe you’ve been trying to execute them in series, but they end up executing out of order. Or maybe you’ve been trying to execute them concurrently, but they end up executing one-at-a-time, in series.

In this post we’ll explain both methods.

That way, if you have a requirement where you need to ensure each function resolves in order, you will be able to and won’t be scratching your head trying to figure out why the functions are resolving out of order…

And if you need them to be concurrent, you’ll be able to do so and get them to resolve faster than if you were doing it in series.

Series

The easiest way to run an array of async/await functions in series is to use for...of. This will execute them in order, one at a time, and will wait for each to resolve.

constlist=[asyncA,asyncB,asyncC]// each of these are async functions

Concurrently

For executing concurrently, I recommend using Promise.all(). Remember, async/await functions are really just Promises, so you can use Promise.all() to execute them.

constlist=[asyncA,asyncB,asyncC]// each of these are async functions

await Promise.all(list.map(fn=>{fn()}))

Of course, if you want the responses of these async functions, you could do const responses = await Promise.all(list.map(fn => { fn() })), which is nice.

Execution

An in case you were confused about the definitions of the two, execution-wise, this is what series vs concurrent looks like:
Technically, the concurrently executed functions will not all kickoff at the exact same time, but for all intents and purposes, this is what it looks like.

And if you want to see this in code:

returnnewPromise(resolve=>setTimeout(resolve,time))

constsomeFn=async(item)=>{

for(constitem of['first','second','third']){

await Promise.all(['first','second','third'].map(fn=>fn()))

// 2s (roughly) - 'first', 'second', 'third'

Wrapping up

Next time you need to remember how to execute the two types, reference this post. And if you haven’t tried using Promise.all() before, try it out next time you have a scenario where you don’t need all your async functions to execute in order. It’s a nice speed boost, which depending on the scenario, could be a nice boost for your end-user.

Feel like you haven’t quite totally grasped async/await and Promises? I publish new posts every week or two about JavaScript and Node.js, including dealing with asynchronous scenarios. Sign up below to get all my new posts on these topics: