The Problem
There is a bulk edit feature where the user can multi-select a few records and edit all of them at the same time.However when updating 50+ records at once, it can take up to 50 seconds and the page freezes. The users were confused during the wait and often left the page early. We want to make it faster.
Why the Slowness
The code was written like this:
for (r in records) {
await update(r)
}
Updating one record makes an API call that takes 500ms - 1s.And since it iterates over the records and updates them one by one, the time goes up linearly as there are more records to be updated.
Using Promise to Speed Up
Fortunately we don't have to wait for one update to finish before we process the next one. allows us to make the next update request before the previous one finishes. This is what we did:
const allPromises = [];
for (r in records) {
const promise = update(r);
allPromises.push(promise);
};
await Promise.all(allPromises);
Visually this is what happened when using
async/await
v.s. using
promises
:
As we can see, since we are not waiting for each update request to return before making the next one, it saves lots of time.
Be Careful - Promise.all() Is All or Nothing
One thing to keep in mind is that .
This means if any of the promises are rejected,
await Promise.all(allPromises)
will throw an error.
This is not the behaviour I want. In my case, I want to know which records were updated successfully, even if some of them failed.
To achieve this, we used
.then
and
.catch
to make sure the update promises resolve no matter what.
To tell the outcome, we made it resolve to its
id
if succeeded, and
null
if not. This way we were able to get the ids of the successfully updated records:
const allPromises = [];
for ( r in records) {
const promise = new Promise((res, rej) => {
update(t)
.then(() => { res(r.id) }); # succeed
.catch(err => { res(null) }); # failed
});
promiseList.push(promise);
};
let results = await Promise.all(allPromises);
results = results.map(r => r!==null);
Note that in your case you might want to use something that suits your requirement.Visually this is what happened now if some update requests failed:
And we were able to use the returned array to tell which records were updated successfully.That's it! We were able to reduce a bulk edit operation of 50+ records from 50+ seconds to less than 5 seconds with this change. 💪
Thanks for Reading!
I hope this is clear and helpful. If you have any questions please don't hesitate to leave a comment.Thanks for your time!