JS Callback functions— What it is and How to use it!!

Rajesh Kumar
5 min readJun 28, 2020

In this article we will discuss about the concept f and usage of Callback functions in the JavaScript Programming language.Callback functions are an important part of JavaScript and once you understand how callbacks work, you’ll become much better in JavaScript.

What is Callback functions in JS?

Suppose you are calling your friend XYZ to discuss something ,but someone else pick up the call and told you that XYZ is not available right now.And you ask him to inform XYZ to call back you return when he/she is available and when XYZ available he/she called you back.

This same concept apply with Callback in JS.

A callback function is a function that is passed as an argument to another function, to be “called back” at a later time.

NOTE:

  • functions are first-class objects. As such, we can work with them in the same way we work with other objects, like assigning them to variables and passing them as arguments into other functions.
  • A function that accepts other functions as arguments is called a higher-order function, which contains the logic for when the callback function gets executed.

Let’s see a simple illustration of Callback —

function getMessage(guestName,callBack){let welcomeMsg = `Welcome ${guestName}`;
callBack(welcomeMsg);
}
function displayMessage(msg){
console.log(msg);
}
getMessage("John",displayMessage); // Welcome John

In the above we have two function i.e getMessage to get the message with guestName and displayMessage to print the message that received, we have sent “XYZ” string and displayMessage function as parameter input. After initializing the welcomeMsg we have callBack the displayMessage.

Many of you understand the meaning of callback function but thinking right now that what is the use of it? and where we have to use? 🤔

Let’s understand that the use of callback functions.

Use of Callback functions in JS

Before discussing of the use of it,first let’s understand the problem that is solved by callback and then it will be much more easy for all of you.

In JavaScript. code runs sequentially in top-down order. For example:

function displayInformation(){
console.log('Name:John');
console.log('Marks:20');
console.log('City: ABC');
}
displayInformation();
//--Output---
//Name:John
//Marks:20
//City: ABC

In the above all information print sequentially from top to down as output displayed.

However, there are some cases that code runs (or must run) after something else happens and also not sequentially. This is called asynchronous programming.

Suppose In the above example,Marks is fetching from the database through an API Call and Information of city will be print only after marks is available and API call takes 1 sec to fetch the marks data from the database.(To do that i have added setTimeout(fun,delay) to delay 1 sec of code execution)

function displayInformation(){
console.log('Name:John');
setTimeout(()=>{console.log('Marks:20')},1000);
console.log('City: ABC');
}
displayInformation();
//--Output---
//Name:John
//City: ABC
//Marks:20

If you run the above code ,the output is not coming as expected. marks is printing at the last after City ,but it should be printed before City.

This is happening because above program is an example of asynchronous programming where we expect to display the marks information before city.But JS is synchronous in default nature(i.e execute the program top to down i.e sequentially and don’t wait for execution end of something.)

To solve this kind of problem ,Callbacks functions comes into the picture.

Note: In the above example ,setTimeout is also a callback function which receives an function and execute only after specified delay time

Now we will see how to use callback functions!!

How to use callback function?

let’s solve the above problem with callback function.

function getCity(){
console.log('City: ABC');
}
function displayInformation(callBack){
console.log('Name:John');
setTimeout(()=>
{
console.log('Marks:20');
callBack();
},1000);
}
displayInformation(getCity);
//--Output---
//Name:John
//Marks:20
//City: ABC

Now we got the right output.In the above we created a new function getCity that is used as callback function ,that will be calling only after marks get displayed.

So In simple words , we create a function that is execute only after certain condition and pass that function as parameter and call it after the code that we want to execute first!!

Now another thing is that, we can also use callback into another callback function.Let’s see.

Suppose we want to displayCount 1 , if 1 is available display 2 and 3 if 2 value is available all these data fetched from an API call so we have to also handle the error through if-else block:

function handleError(error){
console.log(error)
}
function displayCount(count,callBack){
console.log(`Count:${count}`);
callBack();
}
displayCount(1 ,function(err){
if(err){
handleError(err);
}else{
console.log('1 is available');
displayCount(2,(err)=>{
if(err){
handleError();
}else{
console.log('2 is available');
displayCount(3,(err)=>{
if(err){
handleError(err);
}else{
console.log('3 is available');
}
});
}
})
}
});
//---Output---
//"Count:1"
//"1 is available"
//"Count:2"
//"2 is available"
//"Count:3"
//"3 is available"

In this above,we have created displayCount to display the number and after that a callback is invoked whatever function is passed as parameter and a handleError function to print the error.

Firs we have called displayCount and passing 1 as parameter and a function without any name (i.e called as anonymous function) as callback ,which will be invoked after count is displayed.Then inside we are checking if any error is available print the error and end the next execution of function.And if there is no error Then inside first Callback again invoking displayCount and passing 2 as parameter and an arrow function as callback. Similarly for next count 3 input parameter.

In this way we can acheive callback inside another callback function!! when there is small nesting condition for callback.

But you have noticed that code has quiet nested and readability has decreased.

As calls become more nested, the code becomes deeper and increasingly more difficult to manage, especially if we have real code instead of ... that may include more loops, conditional statements and so on.

nested pyramid

That’s known as “callback hell” or “pyramid of doom.”

We can try to alleviate/solve the problem by making every action a standalone/individual function, like this:-

function handleError(error){
console.log(error)
}
function thirdAvail(err){
if(err){
handleError(err);
}else{
console.log('3 is available');
}
}
function secondAvail(err){
if(err){
handleError(err);
}else{
console.log('2 is available');
displayCount(3,thirdAvail)
}
}
function firstAvail(err){
if(err){
handleError(err);
}else{
console.log('1 is available');
displayCount(2,secondAvail)
}
}
function displayCount(count,callback){
console.log(`Count:${count}`);
callback()
}
displayCount(1,firstAvail);
//---Output---
//"Count:1"
//"1 is available"
//"Count:2"
//"2 is available"
//"Count:3"
//"3 is available"

Now there is no deep nesting, because we have made every action a separate top-level function.

It will work, but the code looks like a long spreadsheet. So It’s difficult to read, and you probably noticed that one needs to eye-jump between pieces while reading it. That’s inconvenient, especially if the reader is not familiar with the code and doesn’t know where to eye-jump.

In JS,there are other ways to avoid such pyramids. One of the best ways is to use promise. I will cover this topic in next article!!😊

That’s it for closure !! I hope now you will have the good understanding about callback functions.

If you really liked this article click the clap 👏button below. Also write your feedback and queries in comment section.

--

--