Javascript Async Await Tutorial
In this tutorial, we are going to have a look at how you can make your
JavaScript programs more syntactically beautiful with the use of both the
async
and await
keywords. Both of these keywords were introduced into Node
in version 7.6. Hopefully, by the end of the tutorial, you will be going back to
refactor all of your old NodeJS based applications to replace all of your
chained callbacks and promises.
A Simple Introduction
Let us first have a look at how we would typically deal with functions that
return promises without async
or await
. We’ll create a myPromise()
function which will just return a Promise
like so:
function myPromise() {
return new Promise((resolve, reject) => {
resolve("My Promise Response");
});
}
Let’s now try and call the myPromise()
function within a traditional function.
This will mean we have to again return a Promise
and only resolve this
returned Promise
once we have the result from our myPromise()
function. Like
so:
function myTraditionalFunction() {
return new Promise((resolve, reject) => {
myPromise().then(result => {
resolve(result);
});
});
}
myTraditionalFunction().then(x => console.log(x));
Now this isn’t too bad for a simple program, but consider what happens when our programs grow in size and complexity, we’ll then have to deal with hundreds of chained promise functions and our codebase will be needlessly complex.
Let’s have a look at how we can improve this with the use of async
and
await
. We will create a myAsyncFunction()
which will be prepended by the
async
keyword. Within the function body, we can then get
async function myAsyncFunction() {
var resp = await myPromise();
return resp;
}
function myPromise() {
return new Promise((resolve, reject) => {
resolve("My Promise Response");
});
}
myAsyncFunction().then(x => console.log(x));
We’ve managed to achieve the same result with our myAsyncFunction
in 4 lines
of code, as we had with 8 lines of code in our previous myTraditionalFunction
.
By utilizing the async
and await
keywords, we have been able to create a
program that is far cleaner and more concise.
Improvements to Error Handling
Using both async
and await
improves the way we can deal with errors that
occur inside of our promises. Let’s take for example a program that crawls a
page of a website and returns the response, using traditional error handling
methods we would have to write additional .catch()
blocks to catch any errors
that our promises may throw.
With the await
keyword however, we can simply wrap our promise within a try
catch like so:
const axios = require("axios");
async function crawlPage(url) {
try {
let result = await axios.get(url);
console.log(result);
} catch (err) {
console.log(err);
}
}
crawlPage("https://tutorialedge.net/");
This is far cleaner and simpler than using the .catch()
block approach. Let’s
flesh this sample out a little and create a very simple web crawler that can
retrieve all of the links on a given page:
const axios = require("axios");
const cheerio = require("cheerio");
async function crawlPage(url) {
try {
let result = await axios.get(url);
$ = cheerio.load(result.data);
links = $("a");
$(links).each((i, link) => {
console.log(i);
console.log($(link).attr("href"));
});
} catch (err) {
console.log(err);
}
}
crawlPage("https://tutorialedge.net/");
Conclusion
Hopefully, you found this tutorial useful and I’ve shown you the light when it
comes to using async
and await
within your own JavaScript programs. I would
love to hear your feedback so please feel free to reach out to me on twitter:
@Elliot_F.