How to perform Asynchronous actions using Promises (the right way)

Loading stuff into your web page means that you have to choose between making in series calls or in parallel, the last option is certainly a nice thing to do if you have multiples asynchronous actions that are not dependent on each others, cutting into data load times by launching bunch of parallel calls to our dear API to handle, but by doing this we are loosing the control on how and when our calls will be fulfilled, thus resulting in data being loaded in random order depending on which one resolved first.
As we know, asynchronous requests can finish at any time, so there is no way to guarantee in which order our data would get created.
Usually in the Javascript realm we’ll be using Promise.all() in order to get the the most of our precious time so we don’t leave our user staring into a blank page 😑.

The benefit of parallel requests are clearly undoubtable but it comes with a great pitfall. To put things in context let’s take an example where we load multiple images of dogs into a web page, following a precise order of the dog breeds in an alphabetical order. For this example we will be using the DogAPI.
We have the following constant consisting of a sorted array of strings representing the dog breeds, as you can see the breeds are already in alphabetical order and let’s suppose our main focus is to make the cute akita doge pop first!

The initial code palatalization is pretty straightforward if you are accustomed to Promises and the Fetch API. Usually it will look like something like this:

The getDogs() will call getRandomDog() for each breed of the breeds array and then the loadDog() will take care of appending our images to the document. The network requests here are all executed in parallel using Promise.all():

I hope by now you did notice what’s the problem with this code. Even if it’s looks fine, something unexpected will happen. You guess it right! the dogs will be created out of order but more than that we will be waiting for all the requests to be settled (fulfilled or rejected) before we display anything to our users which is a real bummer 😵
A small modification to our code can lead to great improvements and in order to do this we should exploit two important concepts that Promises offer to us : Thening & Chaining:

So our goal here is to make sure to load all the dogs in the right order without waiting for all the Promises to be settled while keeping it in parallel which guarantees that all the networks calls are made in the same time, also time is gold, right? ⏳
Let’s do this! First let’s create a separate array for our Promises. We will take advantage of map() which will execute the requests immediately.

To guarantee the order we must chain all of our Promises to do this. We first declare a chain as a starting point.

All we have to do now is loop through all the Promises and turn them into a sequence by chaining each Promise. At this point we shouldn’t forget that the Promises are executing finally our getDogs() will resemble to something like this:

This way we are checking all the boxes namely:
- Requesting everything is parallel. (All calls are executed at once) 🚀
- All the images are loaded respecting the order of the breeds. 🐕
- No time wasted waiting for ALL the Promises to be settled. (The dog images are loaded as soon as possible) ⚡🏃
- Bonus: Akita is always first 🐶
For the one-liners Nazi they deserve a super tersed version, hold my beer 🍺

The getDogs() is only 3 lines now but I strongly discourage using this short version for a better readability . I’ve set up a demo on JsFiddle so everyone can take a look at it 👀.
That’s pretty much it!
If you found this was useful don’t forget to clap 👏 the button down below a few times 😏. Click follow if you don’t want to miss my upcoming stories!

