Since Node.js version 7.6, Node.js ships with a new V8 version that features async functions. As Node.js 8 becomes the active LTS version on October 31, there is no reason for not starting to adopt async functions in your codebase. In this article, I will briefly show you what async functions are, and how they change the way we write Node.js applications.
async functions let you write
Promise-based code as if it were synchronous. Once you define a function using the
async keyword, then you can use the
await keyword within the function’s body. When the
async function is called, it returns with a
Promise. When the
async function returns a value, the
Promise gets fulfilled, if the
async function throws an error, it gets rejected.
await keyword can be used to wait for a
Promise to be resolved and returns the fulfilled value. If the value passed to the
await keyword is not a Promise, it converts the value to a resolved
If your Node.js applications are already using
Promises, then you only have to start
awaiting your Promises, instead of chaining them.
If your applications are built using callbacks, moving to
async functions should be done gradually. You can start adding new features by using this new technique. If you have to use older parts of the application, you can simply wrap them into Promises.
To do so, you can use the built-in
express supports Promises out of the box, using
async functions with express is as simple as:
Edit 1: as Keith Smith pointed out, the above example has a serious issue - if the Promise gets rejected, the
express route handler would just hang because there was no error handling there.
To fix this issue, you should wrap your async handlers in a function that handles errors:
Imagine you are working on something similar, when an operation needs two inputs, one from a database, and one from an external service:
In this case, what will happen is the following:
- your code will first get the
- then get the
- and finally make the purchase.
As you can see, you can do the first two in parallel, as they have no dependency on each other. For this, you should use the
In some cases, you only need the result of the fastest resolving Promise - in that cases, you can use the
Consider the following code example:
Once running this snippet, you will get a message in your terminal saying something similar:
In the newer versions of Node.js, if Promise rejections won’t be handled, it will bring down the whole Node.js process. Because of this, you should use
try-catch blocks, when necessary:
try-catch blocks you can hide important exceptions, like system errors, which you want to rethrow. To learn more about when you should rethrow, I strongly recommend to read Eran’s post, Learning to Throw Again.
If you do not want to reinvent the wheel and implement the same logic again, and you also want to depend on a battle-tested library downloaded 50 million times a month, you can simply reuse these functions with
async functions as well, using the
I hope you enjoyed this article and learned a lot! 👩🎓👨🎓 If you’d like to get my latest articles right into your mailbox, you can sign up here to my newsletter 📨.
Also, if there is anything you’d like to learn more about and read on this blog, just let me know in the comments sections, or drop me a message on Twitter!