37

Mastering Promise.allSettled in React | by Dylan Kerler | The Startup | Jul, 202...

 3 years ago
source link: https://medium.com/swlh/mastering-promise-allsettled-in-react-9fcecb7da479
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Mastering Promise.allSettled in React

Every year a new version of javascript comes out. This year’s version, ES2020, released with a bunch of cool new features. While a lot of features got a lot of hype, a new method on the Promise primitive called allSettled seemed to slip under the radar — Despite the fact it’s great!

Let’s see when, why, and how you would use it.

Say we have a page that holds three inputs. One that updates a number, one that updates a username and one that updates a colour. When a user clicks Submit we will send three requests to the server (each to their respective endpoints) to update those values:

Image for post
Image for post

At the moment, if any of our requests fail we don’t do anything. Let’s add an error message to show to the user if one of the requests fail.

Image for post
Image for post

So we added some extra state to hold the error message and changed the onSubmit function to use a method called Promise.all. If any of the promises in Promise.all reject then it will call our catch handler with the first promise that rejected. The downside to this is that can only handle a single error. If more than one request fails, we will only show the errorMessage of the first promise that rejected; The other promises that rejected will be ignored and no errorMessage will be shown for it. That’s not good!

This is where Promise.allSettled comes in to play. Promise.allSettled will wait for every promise in the array, regardless of whether it rejects and will call our .then() function with an array of the results and their statuses for each promise. This means that we can now display an individual errorMessage for each request that failed. Let’s look at some code:

Image for post
Image for post

The first thing we changed was our errorMessage to become errorMessages (plural) since we can now handle multiple errors. The second thing was introduce Promise.allSettled . And then in the .then function we loop over the result of .allSettled which might look something like this:

Image for post
Image for post

We filter the array so that we only have rejected promises, then map the rejected promises into an array of strings that just contains the reason.

Awesome! So by changing from .all to .allSettled, we maintained the benefit of firing multiple requests at once, got access to every errorMessage instead of just one and got to use a cool new feature.

Other Considerations

Some of the more astute readers would note that there are actually other ways to solve this problem instead of using .allSettled. However, these solutions, while they may look good on the surface, have some downsides to them in comparison to using .allSettled. Let’s take a look at some examples:

Switching to async/await:

Image for post
Image for post

The downside to this method is that the requests happen synchronously; We have to wait for one request to resolve, then the next request, then the next request etc. Which means that performance-wise this loses out to Promise.allSettled — Which fires all of the requests at the same time.

Switching to multiple .catch() calls:

Image for post
Image for post

The downside to this is that we cannot guarantee the that results will all conclude at the same time. It might be that the first request takes 1 second to reject but the second request takes 3 seconds to reject. This means that we will show one errorMessage after one second and then another errorMessage will popup 3 seconds later — That leads to some pretty bad user experience!


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK