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 !
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:
userId
, a.k.a your query(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.
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 :)
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:
async
so we can use await
inside the functionconst 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.try/catch
for error handlingPromisify
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>
A throw
will return a promise that reject on error:
Implementing the sleep
function:
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 ?
await Promise.all(...)
will wait for multiple parallel promises to resolve:
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 !