How to use ES8’s Async (and Await) to write concise promise-returning functions
It’s no secret (nor surprise) that async
/await
is one of the most anticipated features of ES8/ES2017. While there are lot of great resources already about the magic of the await
keyword, its unsung sidekick async
hasn’t gotten the same attention.
If you’ve used async
/await
before, you know that async
is what allows await
to work and is required in the nearest-parent function declaration of any use of the await
keyword. Without async
, await
would just block code execution. That would negate JS’s asynchronous nature, one of JS’s best features and the reason JS can be used server-side (e.g. in Node). In order to do this, async
makes the function, well, asynchronous by making the function return a promise, allowing other code to continue running while it await
s.
The side-effect of this is that async
makes writing promised-based asynchronous functions both simple and synchronous-like:
- The promise returned by an
async
function resolves using.then()
— just like any other promise — when the function returns, with the value that is returned — just like a synchronous function - The promise returned by an
async
function catches an error using.catch()
when the function throws an error
Let’s say we have a function that returns a promise that resolves after it gets some data from an API. Using promises, this might look like the following:
const withPromise = () => {
return new Promise((resolve, reject) => {
request(‘https://google.com')
.then((data) => {
// Pass data to promise resolution
resolve(data);
})
.catch((err) => {
// Reject with error
reject(err);
});
});
}
Which requires instantiating a new Promise object, then calling .then, .catch, resolve and reject function. Promises require a lot of baggage to get them to work, not to mention a whole set of vocabulary unique to them.
Using async, we can achieve the same in a few lines
const withAsync = async () => {
try { return await request(‘https://google.com') }
catch (err) { throw err }
}
Which not only is concise and reads just like synchronous code, but will return a promise just like the first snippet.
withPromise().then(data => console.log(data));
withAsync().then(data => console.log(data));
(The above snippets use request-promise
, a module to make http requests that return promises. They’re also trivial functions that just wrap around the the request method. Also on Medium.)