Async await
Making asynchronous programming easier with async and await
Suboor Khan
Software Engineer
More recent additions to the JavaScript language are async functions and the await keyword, added in ECMAScript 2017. These features basically act as syntactic sugar on top of promises, making asynchronous code easier to write and to read afterwards. They make async code look more like old-school synchronous code, so they're well worth learning. This article gives you what you need to know.
There are two parts to using async/await in your code.
The async keyword
First of all we have the async keyword, which you put in front of a function declaration to turn it into an async function. An async function is a function that knows how to expect the possibility of the await keyword being used to invoke asynchronous code.
async function hello() { return "Hello" };
hello().then((value) => console.log(value))
Ah. Invoking the function now returns a promise. This is one of the traits of async functions — their return values are guaranteed to be converted to promises.
To actually consume the value returned when the promise fulfills, since it is returning a promise, we could use a .then() block:
So the async keyword is added to functions to tell them to return a promise rather than directly returning the value.
The await keyword
The advantage of an async function only becomes apparent when you combine it with the await keyword. await only works inside async functions within regular JavaScript code, however it can be used on its own with JavaScript modules.
await can be put in front of any async promise-based function to pause your code on that line until the promise fulfills, then return the resulting value.
You can use await when calling any function that returns a Promise, including web API functions.
Here is a trivial example:
async function hello() {
return greeting = await Promise.resolve("Hello");
};
hello().then(alert);
Rewriting promise code with async/await
Let's look at a simple fetch example
fetch('coffee.jpg')
.then(response => {
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
return response.blob();
})
.then(myBlob => {
let objectURL = URL.createObjectURL(myBlob);
let image = document.createElement('img');
image.src = objectURL;
document.body.appendChild(image);
})
.catch(e => {
console.log('There has been a problem with your fetch operation: ' + e.message);
});
By now, you should have a reasonable understanding of promises and how they work, but let's convert this to use async/await to see how much simpler it makes things:
async function myFetch() {
let response = await fetch('coffee.jpg');
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
let myBlob = await response.blob();
let objectURL = URL.createObjectURL(myBlob);
let image = document.createElement('img');
image.src = objectURL;
document.body.appendChild(image);
}
myFetch()
.catch(e => {
console.log('There has been a problem with your fetch operation: ' + e.message);
});