Photo by Joshua Reddekopp on Unsplash
Async and await in Javascript.
The concept of async and await in javascript.
The concept of async and await is a very useful tool when it comes to asynchronous codes. It is a concept that makes writing promise-
based code easier.
What is a promise?
Though the concept of the promise
is one of the prerequisites to understanding how async
and await
keywords works, this article will like to refresh our memory about promise
. The first step in understanding async
and await
is to understand its very foundation which is promise
. According to the web docs on javascript, a promise
is an object that returns a value upon the completion or failure of an asynchronous method or function (an asynchronous function will be explained later on). The main purpose of a promise is to make an asynchronous function return values like the synchronous function. A promise has three states:
pending: the initial state, the operation has not been fulfilled or rejected yet
fulfilled: meaning the operation was completed
rejected: meaning the operation failed
A promise
is either resolved and returns a value or it's rejected due to a reason. More information on a promise
is here.
What is an asynchronous function?
Javascript is a synchronous language which means the instructions are executed one after the other. Look at the code block below:
let a=3
let b=4
let result=a+b
console.log(result)
The code block above shows the instructions are executed one after the other i.e. it's a synchronous function. This method however has some limitations for example: if we are to fetch some data at multiple points in our code, using the synchronous method becomes a problem; however, this problem can be addressed by using the asynchronous method. An asynchronous method can be thought of as the opposite of the synchronous method meaning the instructions are not executed one after the other and the code can start now and finish later. The setTimeout
function in javascript and promise
are asynchronous methods.
let name="Sicario"
setTimeout(function(){
console.log("asynchronous"
},2000)
console.log("synchronous")
console.log(name)
From the code block above, the values logged to the console will follow this sequence:
synchronous
Sicario
asynchronous
It follows this sequence because the setTimeout
function is an asynchronous function so according to the code after 2000milliseconds(2 seconds) the code in the setTimeout
function will be executed. Now that we know the differences between synchronous and asynchronous methods, we move to the async
and await
keywords.
Prerequisites
To follow up with this concept of async
and await
explained in this article you must have at least a basic understanding of a few things, which include:
Functions
Arrow function expressions.
Classes.
Objects.
Promise.
async
and await
keyword
For ease of comprehension, the async
keyword can be addressed as the abbreviation of "asynchronous"; therefore, when will we see the async
keyword before a function it makes the function asynchronous.
async function name(params){
statemets}
// name= name of the function
// params= the parameters of the function
// statemets = what the function is expected to do.
The code block above shows how to use the async
keyword to make a function asynchronous.
In the case of the await
keyword, as the name suggests, this keyword makes the function wait i.e suspends the execution of the function and resumes with the outcome (either resolved or rejected) of a promise
. The await
keyword can only be used with the async
keyword, else we get an error like this:
async function sum(a,b){
let promise =new Promise((resolve,reject)=>{
setTimeout(()=>{resolve(a+b)},2000)
})
let result= await promise//result is the summation of a+b
console.log(result)// the result will be logged to the console
}
sum(2,8)// we call the sum function
When you look at the code block above, imagine this in your head: when the execution of the code gets to the line which the await
keyword is used, the await keyword behaves like a pause button, meaning the execution will pause at the line the await
keyword is used which will give time for the function to -give the function time to get some data- calculate the sum of a and b as shown above. When the outcome of the sum has been calculated, the outcome of the code whether resolved or rejected will act as the play button for the execution of the code to continue. Let's look at another example:
async function displayName(){ //"async" makes the function asynchronous
let mypromise=new Promise((resolve,reject)=>{
resolve("My name is Sicario");// result of the resolved promise
});
let myname=await mypromise; // wait till the promise is resolved
alert(myname);
}
displayName();
How to infuse async
and await
into your code.
One of the challenges faced by a lot of junior developers is how to use a newly learned concept in a project or while practicing. Now that you understand what async
and await
is, this section will give some examples of ways we can use async
and await
. Some of the ways are:
Fetching data from an endpoint.
Error handling.
Methods for class and objects.
Fetching data from an endpoint
Fetching data from an endpoint or some other source, the concept of async
and await
is quite common in this case. Let's explain this with some blocks of codes:
async function myfetch(url){
try{
let the_fetch=await fetch(url) //fetching the data from an endpoint
let result=await the_fetch.json() // converting the data to json
console.log(result)
}
catch(err){
console.log(err)//logging the error to the console
}
}
myfetch("http://swapi.dev/api/planets/1")// calling the function
From the code above, the concept of async
and await
is quite clear; however, we can decide not to use try...catch
and use throw
for the error message, the code will look like this:
async function myfetch(url){
let the_fetch=await fetch(url)
if(the_fetch.ok){
let result=await the_fetch.json()
console.log(result)
}
else{
throw new Error("Error occured")// to throw an error in case of any
}
}
myfetch("http://swapi.dev/api/planets/1")// calling the function
The endpoint used in the code is the Starwars movie api.
Error handling
The code block above already shows some ways to handle errors in asynchronous functions. Some of the common ways to handle errors in asynchronous functions include: try...catch
block and the throw
keyword. We can use these two methods of error handling in combination with async
and await
Let's take a look at the try...catch
block, as the name implies you try some line of code and then you catch an error if any should occur, that's all to it.
async function Addition(a,b){
try{
let add=new Promise ((resolve,reject)=>{
resolve(a+b)
})
let result=await add
console.log(result)
}
catch(err){
console.log(err)
}
}
Addition(3,7)
So when you run this code, the code within the "result" variable will wait for the code assigned to the "add" variable to be executed since we use the await keyword, and if we have any error in the code the catch block is watching out for that.
Let's take a look at one of the codes above one more time:
async function myfetch(url){
let the_fetch=await fetch(url)
if(the_fetch.ok){
let result=await the_fetch.json()
console.log(result)
}
else{
throw new Error("Error occured")
}
}
myfetch("http://swapi.dev/api/planets/1")
in this case, we use the throw
keyword to throw out error messages instead of the catch
block, and we can hardcode whatever error message we want.
Methods in classes and objects
When we want to define a method in a class or an object, using the async
and await
keyword the syntax will look like this:
class Success {
async wait(){
let response= new Promise((resolve,reject)=>{
resolve("Successful")
})
let result=await response
console.log(result)// "Successful" gets logged to the console
}
}
new Success()
.wait()// calls the method in the class
You can see in the code block above, We prepend the function with the async
keyword and await
keyword waits for the value of the promise. This is identical to the way we use async
and await
keywords to define functions outside of classes or objects.
Conclusion
Let's go over the main functions of the two keywords.
async:
Convert the function to an asynchronous function(by prepending the function with the
async
keyword).Allows the await keyword to be used within the function.
Allows the function to be able to return a promise.
await:
- It waits for a promise to be resolved and returns the result; otherwise, if the promise is rejected it returns an error.
The combination of the async
and await
keyword makes it easy to write asynchronous and promise based code; however, the use of async
and await
keyword is not a total replacement for promise
rather it's a concept based on how promise
works.