Callback & Callback Hell

Callback & Callback Hell

What is a callback?

A callback function is a function that is passed into another function as an argument, which is then invoked inside that outer function after when a specific task is completed.

// add function
function add(x,y){
    return x+y
}

// multiply function
function multiply(x,y){
    return x*y
}

// compute function will accept a function
function compute(x,y,cb){
    return cb(x,y)
}

// passing add function to compute function
let sum = compute(3,6,add)

// passing multiply function to compute function
let product = compute(3,6,multiply)

console.log(sum) // 9
console.log(product) // 18

addEventListener: This function also accepts a callback function.

const button = document.querySelector('button')

function clicked(){
    console.log('clicked')
}
// Passing a callback function clicked
button.addEventListener("click", clicked)

Array methods like map, filter & reduce also accept a callback function.

const myArray = [1,2,3,4]

let square = myArray.map((currEle) => currEle**2)

console.log(square) // [ 1, 4, 9, 16 ]

When we pass a callback function to another function, only the function's reference is passed as an argument and due to this, we do not add round brackets with the function name while passing it as a callback.

Need for Callback Functions

We need callback functions to make sure that a function is only going to get executed after a specific task is completed and not before its completion.

For example, we are fetching data from a URL after fetching the data we want to return that data:-

function fetchingData(url){
    // Fetching content from url
    // Fetching data can take some

    console.log("Fetching Data")
    setTimeout(()=>{
        console.log("Data fetched")
        let response = "Dummy Data"
        // returning data
        return response
    },3000)
}

let res = fetchingData("www.google.com")
console.log(res)

/*
Output -

Fetching Data
undefined
Data fetched
*/

In the above code, the fetchingData function is returning undefined because we are returning the fetched data before it is fetched. Fetching data is an asynchronous task i.e it will happen in the future. To solve this problem we use the callback function.

function fetchingData(url, callback){
    // Fetching content from url
    // Fetching data can take some

    console.log("Fetching Data")
    setTimeout(()=>{
        console.log("Data fetched")
        let response = "Dummy Data"
        callback(response)
    },3000)
}

fetchingData("www.google.com", (res)=>console.log(res))

/*
Output -

Fetching Data
Data fetched
Dummy Data
*/

In the above code, after fetching the data, we passed the fetched data to the callback function, now the fetchingData function will return the fetched data because the callback function will only be invoked after the data is fetched not before it.

A callback can be Synchronous or Asynchronous

Synchronous Callback Function

console.log('Start')

function divide(a, b) {
  console.log(a / b)
}

function operation(val1, val2, callback) {
  callback(val1, val2)
}

operation(16, 4, divide)

console.log('End')

// Output
Start
4
End

The above code is running sequentially, line by line i.e synchronously.

Asynchronous Callback Function

console.log('Start')

setTimeout(() => {
  console.log('We are in the setTimeout()')
}, 3000)

console.log('End')

// Output 
Start
End
We are in the setTimeout()

The above code is not running sequentially. The console.log("End"); statement gets executed before the setTimeout() function. This is called asynchronous programming.

setTimeout() function takes two parameters the first one is a callback function and the second parameter is the time value in milliseconds. The callback function will get executed after the amount of time specified in the second parameter.

Callback Hell

Callback hell is a phenomenon where multiple callbacks are nested into each other. Every callback depends on/waits for the previous callback, thereby making a pyramid structure that affects the readability and maintainability of the code.

It kinda looks like this:

firstFunction(args, function() {
  secondFunction(args, function() {
    thirdFunction(args, function() {
      // And so on…
    });
  });
});

Solutions to callback hell

  1. Using Promises

  2. Using Async/await

We will discuss Promises and Async/await in upcoming articles.

Final Words

And that’s it for this blog.

I hope you’ve found this blog a good referencing resource and thank you for reading.

If this blog was helpful, please do like, comment and share. Thanks, see you in the next blog.✌️