Introduction
The async
and await
keywords aren't so much a competitor to the things we use to deal with Asynchronous code in JS currently (Promises and callbacks). They are actual syntactic sugar over Promises. They allow use to have much cleaner syntax when dealing with Promises. They also make our code much more readable. Let's take a look:
Example with Promises
Let's take a look at a common example that we might see inside of a controller environment:
class UserController {
static getUsersAndPosts(req, res, next) {
getUsers().then(users => {
getPosts().then(posts => {
res.render("users", { users: users, posts: posts })
})
})
}
}
This code will retrieve all users from our database environment. Then pass those users to an anonymous function. Then retrieve all posts from the db and pass it to another anonymous function. Then finally, render the users
template and pass the users
object and the posts
object.
This code works. But, it's pretty ugly... Let's just make it pretty!
Example with Async/Await
Now, we're going to do the exact same thing, but use the async
and await
keywords this time:
class UserController {
static async getUsersAndPosts(req, res, next) {
const users = await getUsers()
const posts = await getPosts()
res.render("users", { users: users, posts: posts })
}
}
So. Much. Cleaner.
async
Let's talk about what each of these keywords do. async
and await
only work together. You can't use them by themselves as they won't do anything. async
is applied when you declare a function. This tells your application that there will be asynchronous operations inside of that function. Let's see some more examples:
async function getUsers() {
// ...
}
const getPosts = async () => {
// ...
}
const songTitlesByAlbum = album.songs.map(async song => {
return await getSongTitle(song)
})
The async
keyword can be applied to ANY valid JS function/method
await
await
is always (and only) used inside of async
functions/methods. We apply it to the actual asynchronous functionality and this makes your application treat that as a synchronous (or blocking) procedure. This means that we're going to pause any other operations and wait for the result from that procedure before moving on to any other code. That means instead of dealing with callbacks or then()
methods, we can just assign that value to a variable and use it more explicitly.
async function getUsers() {
const users = await User.find()
return users
}
const getPosts = async () => {
const posts = await Post.find()
return posts
}
This syntax makes our code so much more readable.
Conclusion
In conclusion, if you're going to be dealing with asynchronous requests (and you will be), there is no better, more readable way to deal with these requests than getting comfortable with the async
and await
keywords to more efficiently deal with your Promises.