Javascript | Callbacks, Promises and Async/Await
Hello Javascript programmers, welcome to the world of javascript async and await concept
This article is for all those who wants to understand the below topics. I love Javascripting and I am into Javascripts from more than 3 years now.
- Callbacks
- Promises
- Async and Await
This article should help us in understanding few javascript concepts like
- What is Synchronous Operation ?
- What is Asynchronous Operation ?
- What is Callback and an example ?
- What is Promises and an example ?
- How Async and Await works in javascript with example?
What is Synchronous Operation in Javascript ?
This is the most efficient way of getting a task done. Synchronous focuses on getting tasks done one by one or one after another or getting tasks done sequentially. I like this approach as it makes code more easy to understand and debug. This also means that the other tasks waits until their turn arrives.
By default Javascript is synchronous or single threaded. it is designed to do one task at a time.
Let’s look at a simple example. Look at the below code
console.log("I am First")
console.log("I am Second")
console.log("I am Third")
The output on console would be
"I am First"
"I am Second"
"I am Third"
What is Asynchronous Operation in Javascript ?
Asynchronous is exactly the opposite of synchronous operation. Which means the tasks can run independent to each other and no task has to wait for others. This approach is great when you want to make your code more efficient and fast. Imagine if you can do multiple tasks at a time and finish it all. Wow ! how great that would be. Not sure if humans can do this effectively but machines and javascript can.
Let’s look at a simple example. Look at the below code
console.log("David Reached School")
setTimeout(() => {
console.log('Liz reached school')
}, 3000)
setTimeout(() => {
console.log('Bill Reached school')
}, 2000)
console.log("Mike Reached School")
The output on console would be
"David Reached School"
"Mike Reached School"
"Bill Reached school"
"Liz reached school"
If you look at the above output, the output is not in the order in which they are programmed but instead its in the order in which it got completed.
Javascript Callbacks : what’s that ?
In JavaScript, a callback is a function passed into another function as an argument to be executed later. When you pass a callback function into another function, you just pass the reference of the function i.e., the function name without the parentheses () .
OR
A callback function is a function passed into another function as an argument, which is then invoked inside the outer function to complete some kind of routine or action.
An Example
function announce() {
console.log('Yea!, the hot water is ready !')
}
function boil_water(shoutIt) {
console.log('Water is boiling')
setTimeout(() => {
shoutIt()
}, 3000)
}
boil_water(announce)
If you look at the code “boil_water(announce)“, you see that method “announce” is passed as a reference to “boil_water” method and “boil_water” is invoking the reference method when needed. So this becomes a simple example for how to use a callback. Hope its easier to understand.
Javascript Callback Hell: OMG, now what is that ?
I thought callbacks were great and interesting. But, wait ! what’s this now.
let’s look at an example straight away.
setTimeout(() => {
console.log('Sunday')
setTimeout(() => {
console.log('Monday')
setTimeout(() => {
console.log('Tuesday')
setTimeout(() => {
console.log('Wednesday')
setTimeout(() => {
console.log('Thursday')
setTimeout(() => {
console.log('Friday')
setTimeout(() => {
console.log('Saturday')
setTimeout(() => {
console.log('Wow! week is over')
}, 2000)
}, 2000)
}, 2000)
}, 2000)
}, 2000)
}, 2000)
}, 2000)
}, 2000)
Output:
"Sunday" (After 2 seconds)
"Monday" (After 2 seconds)
"Tuesday" (After 2 seconds)
"Wednesday" (After 2 seconds)
"Thursday" (After 2 seconds)
"Friday" (After 2 seconds)
"Saturday" (After 2 seconds)
"Wow! week is over" (After 2 seconds)
The code above is a perfect example of “Callback Hell“. Below are some problem of “Callback Hell“.
- It’s hard to read or poor readability.
- Hard to understand the code.
- It’s even harder to debug
- Difficult to add error handling.
“Callback Hell” is also known as “Pyramid of doom” or “Christmas tree of hell“. No matter whatever different names you give , the problems remains the same.
Don’t worry. “Promises” can help us. I promise you that. But don’t take my words.
Wow ! Promises
“Promises” as designed to help us from “callback hell” and more importantly it helps us to better handle our code and tasks. That’s so relieving to hear.
Now, let’s understand “Promises” better. Promises has few states to go through. Below are more info about them
- Pending : This is just an initial state. Example : Just consider a customer is visiting your shop and going through your menu before making an order.
- Resolved : It’s like customer made an order and they got the order delivered to their hand and they are very happy.
- Rejected : It’s like customer ordered something which is not available and he left the shop without getting anything.
Wow, how easy is this to understand. See i promised you that it will be easy to understand. I keep my promises !!!! . Have a look at the same thing like a flowchart or an image below.
Everything is good so far. Lets write a simple promise example.
var is_printer_on = true
let take_print = (printText) => {
return new Promise((resolve, reject) => {
if (is_printer_on) {
setTimeout(() => {
resolve('Printed :' + printText)
}, 2000)
} else {
reject('Printer is off')
}
})
}
So, this is a very simple method that uses promises to take a print of the given printText. Let’s see how to use this method. This method gives different output based on if the printer is on or off.
ie if “var is_printer_on = true” then printer is ON
else if “var is_printer_on = false“) then printer is OFF
Invoke with Printer = ON
var is_printer_on = true
let take_print = (printText) => {
return new Promise((resolve, reject) => {
if (is_printer_on) {
setTimeout(() => {
resolve('Printed :' + printText)
}, 2000)
} else {
reject('Printer is off')
}
})
}
take_print('hello world')
.then((res) => {
console.log('Success : ', res)
})
.catch((err) => {
console.log('oops!,', err)
})
.finally(() => {
console.log('Have a good day')
})
Output
After 2 seconds
"Success : Printed :hello world"
"Have a good day"
Now lets turn OFF the printer
Invoke with Printer = OFF
var is_printer_on = false
let take_print = (printText) => {
return new Promise((resolve, reject) => {
if (is_printer_on) {
setTimeout(() => {
resolve('Printed :' + printText)
}, 2000)
} else {
reject('Printer is off')
}
})
}
take_print('hello world')
.then((res) => {
console.log('Success : ', res)
})
.catch((err) => {
console.log('oops!,', err)
})
.finally(() => {
console.log('Have a good day')
})
Output
"oops!, Printer is off"
"Have a good day"
Great, so you just saw a promise that can take the “Resolved” state when Printer was ON and it took a “Rejected” state when Printer was OFF. And irrespective of the state we got the finally block also executed. So I hope “promises” are now making sense.
Async / await
“Promises” were introduced in javascript to handle asynchronous activity or operation easily. The Async/Await is a syntactical sugar added to easily work with promises. The intention is that async/await will help in making the code look synchronous while performing asynchronous activity.
So let’s write the same “take_print” promise using the async / await keywords. We might need to make slight changes to the “take_print” method and the way it needs to be invoked.
Invoke with Printer = ON
var is_printer_on = true
let take_print = async (printText) => {
return new Promise((resolve, reject) => {
if (is_printer_on) {
setTimeout(() => {
resolve('Printed :' + printText)
}, 2000)
} else {
reject('Printer is off')
}
})
}
async function testcode() {
try {
let res = await take_print('hello world')
console.log('Success : ', res)
} catch (err) {
console.log('oops!,', err)
} finally {
console.log('Have a good day')
}
}
testcode()
Output
After 2 seconds
"Success : Printed :hello world"
"Have a good day"
Invoke with Printer = OFF
var is_printer_on = false
let take_print = async (printText) => {
return new Promise((resolve, reject) => {
if (is_printer_on) {
setTimeout(() => {
resolve('Printed :' + printText)
}, 2000)
} else {
reject('Printer is off')
}
})
}
async function testcode() {
try {
let res = await take_print('hello world')
console.log('Success : ', res)
} catch (err) {
console.log('oops!,', err)
} finally {
console.log('Have a good day')
}
}
testcode()
Output
"oops!, Printer is off"
"Have a good day"
Conclusion
Thanks for reading this article with patience. I hope my article was useful and made sense. Let me know your comments and thoughts through the comment box below. You can read the same article on my medium blog here
Thanks for reading !! Have a great day !
You can buy me a coffee , if you like
Hi! Sorry i just curious, what template did you use for your website? I want to use it on my website at https://www.gdiz.eu.org
I am using a free wordpress template named “Yoga Coach” by kenta