How To Use JavaScript Async/Await In Parallel
I've adopted some pretty new JavaScript goodies when writing the frontend for Klart.co, a bookmarking service for designers that I'm working on. This post will describe a common pitfall with the new JavaScript await syntax. It won't really bring up the Async keyword other than that the functions called may be declared as async or return a promise. Let's get to it.
A common scenario is to have code that looks similar to this. You want to fetch two resources that don't really depend on each other and without knowing that you're making them execute in serial, you write your code like this:
const user = await fetch('/api/users/current');
const snaps = await fetch('/api/users/current/snaps');
doSomethingCool(user, snaps);
Can you see what's wrong about this code?
It will execute in series instead of dispatching the network requests concurrently. This is a problem since we will wait for the entire first request to finish before even starting the next one. Even worse, these request can seemingly be done completely in parallel since they don't depend on each other. Let's look at how we can write this instead.
const [user, snaps] = await Promise.all([
fetch('/api/users/current'),
fetch('/api/users/current/snaps')
]);
doSomethingCool(user, snaps);
Now, we will fire away both network requests and the result will resolve only after both finishes without error. That's pretty awesome. But what if you want to do something with the user right away and not wait for the snaps (or vice-versa)? You could do that too, by chaining the first Promise.
const [user, snaps] = await Promise.all([
fetch('/api/users/current')
.then(user => {
doSomethingCoolWithUser(user);
Promise.resolve(user);
}),
fetch('/api/users/current/snaps')
]);
doSomethingCool(user, snaps);
Pretty neat right? This may speed up your app significantly if you're doing unnecessary serial requests today. This was a pretty technical article for me. Let me know what you think on Twitter @drikerf 😊.