# Callbacks in JavaScript: Why They Exist

As a software developer you have heard the term known as the callbacks, so the callbacks are most common in the asynchronous flow handling. As we know the JavaScript is the synchronous language it runs the tasks one by one sequentially but in term of handling the time taking tasks like database calls, API calls we called them asynchronous tasks was handle by the callbacks and also promises

So, in this blog we will be deep dive into functions, callbacks, why we need them? what is the callback heel

## what is functions ?

The functions are the block of code where we can receive some parameters such as number, string, Boolean, object also function(callbacks) etc.

In the JavaScript functions are first class function means it have special behavior like we can store the functions in variable, also return them from another function and callback when we need them.

```basic
function greet(name, callback()){
    console.log(name);
    callback();
}
function age(age){
    console.log(age);
}

greet('Nikhil', age(22))
```

Now, in the above example we can see we can pass the function named as "age" to the parameter of function named as "greet"  
but we can say that this is the synchronous type of example where we do not wait it goes step by step. Also forEach(), Map() also are the examples in JavaScript

```basic
[1,2,3,4,5].forEach(element => element*2)

```

in this function we pass the arrow one line function as an argument it also works step by step and need not wait

![](https://cdn.hashnode.com/uploads/covers/69501e8b80eb08d5055e2d2e/2a6607e5-6d92-4486-b157-c223dea73319.png align="center")

## what is a callback function?

definition: A callback is a function that you pass to another function, expecting that other function to "call it back" at some point.

**Real-world analogy**: You call a restaurant and say, "Call me back when my table is ready." The callback is the act of calling you back.

```javascript
// The callback
function whenOrderIsReady() {
  console.log("Your order is ready!");
}

// A function that accepts a callback
function placeOrder(food, callback) {
  console.log(`Preparing ${food}...`);
  
  // Simulate preparation (in real code, this would be asynchronous)
  setTimeout(() => {
    callback(); // Call the callback when done
  }, 3000);
}

// Pass the callback to placeOrder
placeOrder("Pizza", whenOrderIsReady);
```

## why callback exist ?

Let's understand the Asynchronous Programming Problem. with some real life examples so you can relate to callbacks

## Asynchronous Programming Problem

As we all know, the JavaScript is the single threaded language, so it executes step by step and never wait for the asynchronous responses like (DB calling, API calling)

For Example:

```basic
function fetchUserData(userId){
    let userData;

    //api call for the user data takes 2-3 sec
    featch('api/theUserData.com/userId')
    .then(response => response.json())
    .then(data => userData = data)

    
return userData
}
```

```basic
//output:
undefine
```

because JavaScript does not wait for the fetch call to get the data and update to the userData. This is the major problem we face. So that's why the callbacks are exists and make the work simple

same example with the callback:

```basic
function fetchUserData(userId, callback){
    featch('api/theUserData.com/userId')
    .then(response => response.json())
    .then(data => callback(data))
    
}
//this fucntion execute when the data is passed
fetchUserData(1, (userData) => {
    console.log("user data" + userData)
})
```

## The Callback Problem - "Callback Hell"

![](https://cdn.hashnode.com/uploads/covers/69501e8b80eb08d5055e2d2e/07f9eedb-6003-4d1c-846b-9419e1ccb18f.png align="center")

### What is Callback Hell?

When you nest multiple callbacks, code becomes hard to read and maintain. This is sometimes called "pyramid of doom."

**Real-world example: User authentication flow**

javascript

```javascript
// ❌ CALLBACK HELL - Hard to read and debug
function loginUser(username, password, callback) {
  validateInput(username, password, function(error) {
    if (error) {
      callback(error);
    } else {
      fetchUserFromDatabase(username, function(error, user) {
        if (error) {
          callback(error);
        } else {
          verifyPassword(password, user.password, function(error, isValid) {
            if (error) {
              callback(error);
            } else if (!isValid) {
              callback(new Error("Invalid password"));
            } else {
              logLoginEvent(user.id, function(error) {
                if (error) {
                  callback(error);
                } else {
                  callback(null, user);
                }
              });
            }
          });
        }
      });
    }
  });
}

// Using it
loginUser("john@example.com", "password123", function(error, user) {
  if (error) {
    console.log("Login failed:", error);
  } else {
    console.log("Logged in:", user.name);
  }
});
```

**Problems with this approach**:

1.  **Hard to read**: The nesting makes it difficult to follow the logic flow
    
2.  **Error handling is repetitive**: You check for errors at every level
    
3.  **Hard to maintain**: Adding new steps means more nesting
    
4.  **Cognitive load**: Your brain has to track multiple levels of indentation
    

### Why Callback Hell Happens

It happens because asynchronous operations need to wait for each other. You need operation B's result before you can start operation C.

## Summary

The article explores the concept of callbacks in JavaScript, particularly in the context of handling asynchronous tasks. JavaScript, being a synchronous language, executes tasks sequentially, which can be problematic for time-consuming operations like database or API calls. Callbacks, along with promises, are used to handle these asynchronous tasks efficiently. A function in JavaScript can be passed as an argument to another function, stored in a variable, or returned from a function, showcasing its "first-class" nature. The article demonstrates this with examples, explaining how callbacks allow functions to execute once a task is completed, much like a restaurant calling back when a table is ready.

The article further delves into the necessity of callbacks due to JavaScript's single-threaded nature, which doesn't wait for asynchronous operations to complete before moving on. This is exemplified with a function that fetches user data; without callbacks, the function returns undefined because it doesn't wait for the data retrieval to complete. By using callbacks, developers can ensure that subsequent operations depend on the completion of asynchronous tasks, thus avoiding premature execution.

However, the use of callbacks can lead to "Callback Hell," a situation where nested callbacks become difficult to read and maintain, also known as the "pyramid of doom." This occurs when multiple asynchronous operations are dependent on each other, leading to deeply nested code that is hard to debug and extend. The article highlights the challenges of callback hell, such as increased complexity, repetitive error handling, and cognitive overload, emphasizing the importance of understanding and managing asynchronous programming effectively. If you read till the last word, make sure, give some feedback for improvements
