The Power of Promise.all() in JavaScript

Understand the promising function with an exciting use case

Geoffrey Bourne
Better Programming

--

Heart-shaped lockets tied to a fence
Photo by Artem Beliaikin on Unsplash.

This article is not about promises, async/await, or the single-threaded nature of Javascript. It is about the Promise.all() function and how you can bring your independently running functions or tasks together into a beautiful result.

As is often the case, an example or use case will prove useful.

Use Case: Post to Multiple Social Media Networks

Our app Ayrshare’s primary purpose is to provide one API to post across multiple social media networks, such as Twitter, Instagram, Facebook, and LinkedIn.

A user will make an API call (RESTful or via a client package) with the post text, image, and the list of networks to send the post. The API returns the resulting success or error for each network as an array of results.

However, there is complexity behind the scenes.

Each network has its own authorization, workflow, and security requirements. For example, if you attach an image to the post, Twitter requires you to first upload the image, wait for their processing to complete, and send the returned media ID in a new update status call to Twitter. Timings vary, errors can occur for some and not for others, and new networks are added all the time. But from an end-user perspective, they sent the post and the results are returned right away.

Here is a visual (Firebase tech stack overview):

Diagram showing how Ayrshare works

We want to run all the network posts in parallel and collect the results to return to the caller. As the number of networks increases, we ideally want to take no longer than the longest network.

The problem we face is if each network function call is asynchronous, then each function will complete at different times and we won’t be able to return the results in one response.

Promise.all() to the Rescue

If you have a similar problem, Promise.all() is your solution.

“The Promise.all() method takes an iterable of promises as an input, and returns a single that resolves to an array of the results of the input promises.” — MDN Web Docs

In other words, if you call several async functions, you can wait until they all resolve and capture their output in an array.

Let’s see a simple example:

printSquare iterates over an array of ints and squares. Calling getSquare returns a promise because we made it an asynchronous function by adding the keyword async. Technically, we don’t need async since the Math.pow function is synchronous.

The promiseArray is an array of promises waiting to be resolved. When we print the promiseArray:

[ 
Promise { 1 },
Promise { 4 },
Promise { 9 },
Promise { 16 },
Promise { 25 }
]

Close, but what is with those “promises”? Well, as mentioned above, the array is composed of promises waiting to be resolved. They can easily be resolved with Promise.all():

And the results:

[ 1, 4, 9, 16, 25 ]

Perfect! Also, the order of the results is maintained.

Notice that we need to await on Promise.all() since it returns a promise that needs to be resolved.

For those who are curious, here is a real example of Ayrshare’s code that posts to all the networks:

Final Thoughts

Often, Promise.all() is thought of as running in parallel, but this isn’t the case.

“Parallel” means you’re doing many things at the same time on multiple threads. However, JavaScript is single-threaded with one call stack and one memory heap. It is an asynchronous, non-blocking language. This means JavaScript doesn’t run in parallel but rather runs only one function/promise at a time. If the single thread has to wait on something, like the return from an HTTP call, it will move on to another function until the return is complete.

In the case of our array of promises, each promise will be handled one at a time, but JavaScript will switch between each one if the processing needs to wait. While the order of promise resolution in Promise.all() can vary depending on blocking, the final result will be an array of ordered results.

--

--

Co-Founder of ayrshare.com — an API-first platform to automate your social media posts with a few lines of code.