chevron-left chevron-right

Piotr Nalepa Blog webmasterski

Dealing with Promise.all() and a bunch of async functions

This version
Published
Author
Category
JavaScript
Feedback
Write to me · Post on X

This post is 6 years old. Browsers and tools may have changed since then, so check the code against current documentation before you use it.

Recently I've been in the situation where I needed to resolve multiple async functions in paralel. The tricky part was that these functions were written using async/await approach and I was going to use Promise.all() function to resolve all of the async requests at the same time, when all of them are resolved.

I'm not going to tell you much about Promises and async/await. I assume you have already gained proper knowledge regarding how to use them in your project.

Section 1The first approach

In order to handle such situation where I had a bunch of async functions I managed to put them all into an array and use it as a param of Promise.all() function. Just like that:

Example 1JavaScript
1
2
3
4
5
6
Promise.all([
    await dispatch(fetchDataFromOneSource),
    await dispatch(fetchDataFromAnotherSource)
])
.then([data1, data2] => {})
.catch(error => console.log(error))

The code listing above is simplified in order to focus on the most important part.

As you can see, I'm using:

Example 2JavaScript
1
2
3
4
[
    await dispatch(fetchDataFromOneSource),
    await dispatch(fetchDataFromAnotherSource)
]

as an input param of Promise.all(). As we all know, async/await approach is just a syntax sugar for Promises, so I expected to have all promises resolved when data is ready. It works perfectly fine, when all promises are resolved correctly. The then() part is run and everyone is happy.

In my case, there were specific situations when one of the async functions should fail and this should prevent from running a callback of then() part. I expected that catch() will be invoked instead.
I was so wrong! All of it failed silently and except showing errors in the browser console nothing happened in the UI, while it should!

Section 2The second approach

At the time being I was rushed by the deadline and I've come up with a following solution:

Example 3JavaScript
1
2
3
4
5
6
7
8
Promise.all([
    await dispatch(fetchDataFromOneSource)
        .catch(handleError),
    await dispatch(fetchDataFromAnotherSource)
        .catch(handleError)
])
.then([data1, data2] => {})
.catch(handleError)

It solved my problem but it was not the most elegant solution in the world. It bothered me a lot. Duplicated error handlers for each promise was not the most optimal solution in my case.

Section 3The final approach

Finally, after thinking for hours. I realised where was the mistake and how to make the previous version more elegant:

Example 4JavaScript
1
2
3
4
5
6
await Promise.all([
    dispatch(fetchDataFromOneSource),
    dispatch(fetchDataFromAnotherSource)
])
.then([data1, data2] => {})
.catch(error => console.log(error))

This also worked as previously, but the final piece of code looks better and it's less hackish now.

It's worth to mention, that running await Promise.all() allows you to assign its output to a variable and maybe destructure it, if needed, and then proceed with next actions instead of running the then() callback param.

Section 4Summary

By writing this article I wanted to clarify the statement I wrote on Twitter:

I was wrong then. The catch will be invoked when the array of Promises contain the Promise objects itself, not the invokations of async functions.

I hope this article clarified it and it will help you solving issues in your projects.

About the author

Staff Software Engineer

I've been writing this blog since 2009 and building for the web professionally for 14 years. Today I lead the frontend of the Cosmos platform at Bishop Fox, where I've been since day one of the project. Before that I worked at OLX, KUDO, Auto1 and eZ Systems. Here I write about what I've learned in practice: JavaScript, TypeScript, React, CSS and frontend architecture. I've also spoken at conferences across Poland and Europe. Got a question or an idea for a post? Let me know!