How to synchronize your JavaScript function calls with async and await
When ECMAScript 2017 was finalised in June 2017, we get the async/await
constructs that simplify synchronous JavaScript function calls.
Therefore, you may want to use async
and await
to keep your JavaScript lean.
In case you need it, this post shows how you can synchronize your JavaScript function calls with async
and await
.
Understand what async
do to your JavaScript function
First, let us look at the async
construct. We typically place the async
construct in front of a JavaScript function:
async function add(x, y) { return x + y; }
When we place the async construct before the add function, the return value is magically wrapped in a JavaScript Promise. Given that, we can call our add
function in the following way:
add(1, 3).then(alert);
When the JavaScript code is ran by a compatible browser, we will see 4 appearing in an alert window.
Understand what await
does to your JavaScript function call
When you put await
before a Promise
, you make your JavaScript interpreter wait until that Promise is able to return a result.
For example, in the following JavaScript code segment, the alert
function will only run after 1 second:
async function showAdditionResult() { promiseToAdd = new Promise(function (resolve, reject) { setTimeout(function () { resolve(add(1, 3)); }, 1000) }); result = await promiseToAdd; alert(result); } showAdditionResult();
This is because the await
function will block the interpreter till setTimeout
function performs the addition. Therefore, the alert
function will make the browser show an alert window with 4 in the dialog body without fail.
If we want to achieve similar behaviour without the await
construct, then we will have to put the alert function within the then()
function of promiseToAdd
:
function showAdditionResult() { promiseToAdd = new Promise(function (resolve, reject) { setTimeout(function () { resolve(add(1, 3)); }, 1000) }); promiseToAdd.then( function(result) { alert(result); } ); } showAdditionResult();
Indeed by comparing both versions, we can see that the await
construct can help enhance the readability of synchronous JavaScript codes.
Uncaught SyntaxError: await is only valid in async function
If we use await
in a regular JavaScript function, then the interpreter will throw us a syntax error.
For example, our JavaScript interpreter will not be able to interpret the following JavaScript function:
function showAdditionResult() { promiseToAdd = new Promise(function (resolve, reject) { setTimeout(function () { resolve(add(1, 3)); }, 1000) }); result = await promiseToAdd; alert(result); } showAdditionResult();
When we attempt to run the above JavaScript codes in a Chrome browser, we will see the following error message in the console:
Uncaught SyntaxError: await is only valid in async function
Catch errors that may happen
In order to see how errors can be caught while we use the await
function, let's define an async
function that attempt to fetch from a URL:
async function fetchData(url) { response = await fetch(url); if (response.ok) { return response.json(); } else { throw new Error(response.status); } }
Since fetch
only reject on network failure or if anything prevented the request from completing, we explicitly throw an Error
on HTTP error status.
Given that, we try to catch Errors throw by the fetchData
function. When we use the await
construct, we will be able to catch errors easily.
In order to do so, we simply wrap the function call in a try-catch block:
async function testFetches() { try { jsonData = await fetchData('https://httpbin.org/headers'); alert(JSON.stringify(jsonData)); jsonData = await fetchData('https://httpbin.org/status/500'); alert(JSON.stringify(jsonData)); } catch(err) { alert(err); } } testFetches();
When we ran the two previous JavaScript code segments, we simulate a scenario to catch Error
.
Since a HTTP request made to https://httpbin.org/headers will return a response with 200 OK, we will be able to show an alert with the JSON data from the response body.
However, when we try to make a HTTP request to https://httpbin.org/status/500, an Error will be thrown. When that happens, the browser will show Error: 500 in an alert window.