# Callbacks in JavaScript: Why They Exist

JavaScript treats functions as values. That means functions can be stored in variables, passed into other functions, and even returned from functions.

This ability makes JavaScript extremely flexible and is one of the reasons callbacks exist.

Callbacks are especially important in asynchronous programming, where certain tasks take time to complete, such as fetching data from a server or reading a file.

Before understanding asynchronous callbacks, it’s important to first understand that functions in JavaScript can behave like normal values.

* * *

## Functions as Values in JavaScript

In JavaScript, functions can be assigned to variables.

Example:

```javascript
const greet = function() {
  console.log("Hello");
};

greet();
```

Output:

```id="5wz5eo"
Hello
```

Since functions can be stored like values, they can also be passed into other functions.

This concept is the foundation of callbacks.

* * *

## What Is a Callback Function?

A callback function is simply a **function passed as an argument to another function**.

Example:

```javascript
function greet(name, callback) {
  console.log("Hello " + name);

  callback();
}

function sayBye() {
  console.log("Goodbye");
}

greet("Ritesh", sayBye);
```

Output:

```id="g0kbg8"
Hello Ritesh
Goodbye
```

Here:

*   `sayBye` is passed as an argument
    
*   it gets executed later inside `greet()`
    

That is why it is called a **callback**.

* * *

## Understanding Callback Flow

![](https://cdn.hashnode.com/uploads/covers/695e6df5e8d5605ec2e5e7d7/13323d96-8c3c-4a00-9600-478965155ffc.png align="center")

* * *

## Passing Functions as Arguments

Because functions are treated as values, we can directly pass them into other functions.

Example:

```javascript
function calculate(a, b, operation) {
  return operation(a, b);
}

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

console.log(calculate(5, 3, add));
```

Output:

```id="r2y4pq"
8
```

Here:

*   `add` is passed as an argument
    
*   `calculate()` calls it internally
    

This approach makes code reusable and flexible.

* * *

## Why Callbacks Are Used in Asynchronous Programming

Some tasks in JavaScript take time to complete.

Examples:

*   fetching API data
    
*   reading files
    
*   waiting for user interaction
    
*   timers like `setTimeout()`
    

JavaScript does not want to stop the entire program while waiting for these tasks. Instead, it continues running other code and uses callbacks to handle the result later.

Example using `setTimeout()`:

```javascript
console.log("Start");

setTimeout(function() {
  console.log("This runs later");
}, 2000);

console.log("End");
```

Output:

```id="jlwm6x"
Start
End
This runs later
```

The callback function inside `setTimeout()` runs after 2 seconds.

* * *

## Callback in an Async Scenario

![](https://cdn.hashnode.com/uploads/covers/695e6df5e8d5605ec2e5e7d7/fc81711f-09ef-416d-a329-e6aaf9144b5a.png align="center")

* * *

## Common Callback Usage Scenarios

Callbacks are used in many places in JavaScript.

### Timers

```javascript
setTimeout(function() {
  console.log("Timer finished");
}, 1000);
```

* * *

### Array Methods

```javascript
let numbers = [1, 2, 3];

numbers.forEach(function(num) {
  console.log(num);
});
```

The function inside `forEach()` is also a callback.

* * *

### Event Handling

```javascript
button.addEventListener("click", function() {
  console.log("Button clicked");
});
```

When the button is clicked, the callback function executes.

* * *

## The Problem of Callback Nesting

Callbacks are useful, but too many nested callbacks can make code difficult to read.

Example:

```javascript
loginUser(function(user) {

  getProfile(user, function(profile) {

    getPosts(profile, function(posts) {

      console.log(posts);

    });

  });

});
```

This deeply nested structure is commonly called **callback hell**.

As applications grow larger, this style becomes hard to manage and debug.

Modern JavaScript later introduced:

*   Promises
    
*   async/await
    

to solve these readability issues.

* * *

## Visualizing Callback Nesting

![](https://cdn.hashnode.com/uploads/covers/695e6df5e8d5605ec2e5e7d7/eb05bc4a-8039-4320-a19b-d811f18e35dc.png align="center")

* * *

## Assignment Practice

Create a function that accepts another function as a callback.

```javascript
function processUser(name, callback) {
  console.log("Processing user: " + name);

  callback();
}
```

Create a callback function.

```javascript
function completed() {
  console.log("Process completed");
}
```

Pass the callback into the main function.

```javascript
processUser("Rahul", completed);
```

Use a callback with `setTimeout()`.

```javascript
setTimeout(function() {
  console.log("This message appears after 2 seconds");
}, 2000);
```

Experiment with different callback examples in the console to better understand how functions can be passed and executed later.
