JavaScript beyond ES6#3 - ES2017: async
and await
ES2017 introuced a new way of working with promises, called “async/await”.
Promise
review
Before we dive in this new syntax let’s quickly review how we would usually write a promise:
// fetch a user from github
fetch('api.github.com/user/AlbertoMontalesi').then( res => {
// return the data in json format
return res.json();
}).then(res => {
// if everything went well, log the data
console.log(res);
}).catch( err => {
// or log the error
console.log(err);
})
This is a very simple promise to fetch a user from github and print it to the console.
Let’s see a different example:
function walk(amount) {
return new Promise((resolve,reject) => {
if (amount < 500) {
reject ("the value is too small");
}
setTimeout(() => resolve(`you walked for ${amount}ms`),amount);
});
}
walk(1000).then(res => {
console.log(res);
return walk(500);
}).then(res => {
console.log(res);
return walk(700);
}).then(res => {
console.log(res);
return walk(800);
}).then(res => {
console.log(res);
return walk(100);
}).then(res => {
console.log(res);
return walk(400);
}).then(res => {
console.log(res);
return walk(600);
});
// you walked for 1000ms
// you walked for 500ms
// you walked for 700ms
// you walked for 800ms
// uncaught exception: the value is too small
Let’s see how we can rewrite this Promise
with the new async/await syntax.
Async and Await
function walk(amount) {
return new Promise((resolve,reject) => {
if (amount < 500) {
reject ("the value is too small");
}
setTimeout(() => resolve(`you walked for ${amount}ms`),amount);
});
}
// create an async function
async function go() {
// use the keyword await to wait for the response
const res = await walk(500);
console.log(res);
const res2 = await walk(900);
console.log(res2);
const res3 = await walk(600);
console.log(res3);
const res4 = await walk(700);
console.log(res4);
const res5 = await walk(400);
console.log(res5);
console.log("finished");
}
go();
// you walked for 500ms
// you walked for 900ms
// you walked for 600ms
// you walked for 700ms
// uncaught exception: the value is too small
Let’s break down what we just did:
- to create an async function we need to put the
async
keyword in front of it - the keyword will tell JavaScript to always return a promise
- if we specify to
return <non-promise>
it will return a value wrapped inside a promise - the
await
keyword only works inside anasync
function. - as the name implies,
await
will tell JavaScript to wait until the promise returns its result
Let’s see what happens if we try to use await
outside an async
function
// use async inside a normal function
function func() {
let promise = Promise.resolve(1);
let result = await promise;
}
func();
// SyntaxError: await is only valid in async functions and async generators
// use async in the top-level code
let response = Promise.resolve("hi");
let result = await response;
// SyntaxError: await is only valid in async functions and async generators
Remember: you can only use
await
inside anasync
function.
Error handling
In a normal promise we would use .catch()
to catch eventual errors returned by the promise.
Here, it is not much different:
async function asyncFunc() {
try {
let response = await fetch('http:your-url');
} catch(err) {
}
console.log(err);
}
asyncFunc();
// TypeError: failed to fetch
We use try...catch
to grab the error but in a case where we do not have them we can still catch the error like this:
async function asyncFunc(){
let response = await fetch('http:your-url');
}
asyncFunc();
// Uncaught (in promise) TypeError: Failed to fetch
asyncFunc().catch(console.log);
// TypeError: Failed to fetch
This was the third part of my Beyond ES6 course.
You can also read this articles on medium, on my profile.
Thank you for reading.
Leave a Comment