paint-brush
Await is the new blackby@aherve
3,255 reads
3,255 reads

Await is the new black

by Aurélien HervéDecember 7th, 2016
Read on Terminal Reader
Read this story w/o Javascript
tldt arrow

Too Long; Didn't Read

Are you aware of how awesome the new es7 <code class="markup--code markup--p-code u-paddingRight0 u-marginRight0">async/<a href="https://hackernoon.com/tagged/await" target="_blank">await</a></code> feature is&nbsp;? Showtime&nbsp;!

Companies Mentioned

Mention Thumbnail
Mention Thumbnail
featured image - Await is the new black
Aurélien Hervé HackerNoon profile picture

This guy uses await. Look how happy he is.

Are you aware of how awesome the new es7 async/[await](https://hackernoon.com/tagged/await) feature is ? Showtime !

1. At the beginning, there was callbacks

Imagine you are told to order an amazon package, then go grab it at the post office, then come back home to open it.

Simple instructions. Well guess what, most people do not spend 3 days waiting in front of the post office for their package to arrive. Apart the fact that you would probably starve, this doesn’t look like a very efficient way of organizing your workflow. Similar to waiting for an amazon package, the web development is mostly about sending server/database/services request, then wait for it to come back, and do something with the data. It is thus only natural to use a language that is capable of dealing with concurrency.

The callbacks are a way to deal with concurrency. Node users are familiar with code that reads

It basically tells to fetch a user from some database, while passing two parameters:

  • the userId, a.k.a your query
  • the callback function (err, user) => {...} that explains what to do when the query results arrive. As a node convention, the first callback argument is an error message, whose you hope it’s just null

It works, but at some point it becomes tedious to deal with all the error handling, and you’ll probably end up with some incomprehensible, deep-nested code. Many speak of this situation as the callback hell. I’m not quite sure it’s a hell, but it definitely looks boring to me.

2. Enter Promises

Promises are more recent feature that helps chaining asynchronous tasks, while keeping a better readability. Our first example would now read

Wow, much better !

But what if I want to use both user and result as arguments to another function ? This would turn our code into

Aaaand we’re back to multiple nesting levels. How sad :(

Promises are a great thing, and they allowed a tremendous improvement of code readability. They do not however solve all our problems, and nesting/error catching still exists, although it is definitely better than with callbacks.

EDIT: It has been pointed out by clever people that a more honest/elegant way of solving the example2 with promises could read:

It is indeed better than my original solution :)

3. Enter Await

Brace yourselves, ES7 is coming. At the moment async/await is still a proposal, so the following could be subject to (minor I hope) changes.

To use ES7 features, either setup babel, or use typescript (or anything else I didn’t think to mention). As for today, the TS team chose to release a await/async feature, that has the same specs as its ES7 counterpart. Note that this might change someday, though we hope not.

First, let’s update our example:

Here’s a few things to notice:

  • The function is declared async so we can use await inside the function
  • const user = await User.findById(userId)will work as if you were developing in a synchronous world. Although it does NOT block the thread (so it is actually asynchronous), it allows the developer to really express what’s he/she is thinking about: do stuff, name the result, and use them later.
  • Back to good ol’ try/catch for error handling

Examples of cool stuff we can do with await/async

Promisify

An async function always return a promise. You can even use it to “promisify” a regular function:

Notice how declaring the function as async turned return i +1 (a number) into a Promise<number>

Throw

A throw will return a promise that reject on error:

  • Another example ?

Sleep

Implementing the sleep function:

Node.js test example

How about we look at three ways of writing a nodejs test ?

This test count the number of users to check there is more than 1, then fetch one, and check it has an email field.

Which one looks better to you ?

Protip: parallelism

await Promise.all(...) will wait for multiple parallel promises to resolve:

Conclusion

If you’re still here, then I’m pretty sure you now have a decent idea of what’s going on with this much fancyasync/await feature.

I hope you’re now convinced of how awesome it is. Let me know what you think !