const request = require('request');
function getPageHtml(url) {
return new Promise(function(resolve, reject) {
request(url, function(error, response, body) {
resolve(body);
});
});
}
async function main() {
const html = awaitgetPageHtml('http://google.com');
console.log(html);
}
main();
console.log('Loading...');
In this code,there are two functions: getPageHtml and main. The first one is a very simple function that fetches the HTML code of a remote web page given its URL. It's worth noticing that this function returns a promise.
The main function is the most interesting one because it's where the new async and await keywords are used. The first thing to notice is that the function is prefixed with the async keyword. This means that the function executes asynchronous code and allows it to use the await keyword within its body. The await keyword before the call to getPageHtml tells the JavaScript interpreter to "await" the resolution of the promise returned by getPageHtml before continuing to the next instruction. This way, the main function is internally suspended until the asynchronous code completes without blocking the normal execution of the rest of the program. In fact, we will see the string Loading… in the console and, after a moment, the HTML code of the Google landing page.
Isn't this approach much more readable and easy to understand?
Unfortunately, this proposal is not yet final, and even if it will be approved we will need to wait for the next version of the ECMAScript specification to come out and be integrated in Node.js to be able to use this new syntax natively.
So what do we do today? Just wait? No, of course not! We can already leverage async await in our code thanks to transpilers such as Babel.
Installing and running Babel
Babel is a JavaScript compiler (or transpiler) that is able to convert JavaScript code into other JavaScript code using syntax transformers. Syntax transformers allowsthe use of new syntax such as ES2015, ES2016, JSX, and others to produce backward compatible equivalent code that can be executed in modernJavaScript runtimes, such as browsers or Node.js.
You can install Babel in your project using NPM with the following command:
npm install --save-dev babel-cli
We also need to install the extensions to support async await parsing and transformation:
npm install --save-dev babel-plugin-syntax-async-functions babel-plugin-transform-async-to-generator
Now let's assume we want to run our previous example (called index.js).We need to launch the following command:
Unlock access to the largest independent learning library in Tech for FREE!
Get unlimited access to 7500+ expert-authored eBooks and video courses covering every tech area you can think of.
Renews at $19.99/month. Cancel anytime
node_modules/.bin/babel-node --plugins "syntax-async-functions,transform-async-to-generator" index.js
This way, we are transforming the source code in index.js on the fly, applying the transformers to support async await. This new backward compatible code is stored in memory and then executed on the fly on the Node.js runtime.
Babel can also be configured to act as a build processor that stores the generated code into files so that you can easily deploy and run the generated code.
You can read more about how to install and configure Babel on the official website at https://babeljs.io.
Comparison
At this point, we should have a better understanding of the options we have to tame the asynchronous nature of JavaScript. Each one of the solutions presented has its own pros and cons. Let's summarize them in the following table: