# Callbacks in JavaScript: Why They Exist


Hello guys, in this article we are going to learn about the callback functions in the js, what are they , why we use them and the problems we face while using them.

### Callback function

*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 action.*

There are two ways in which the callback may be called: *<mark class="bg-yellow-200 dark:bg-yellow-500/30">synchronous</mark>* <mark class="bg-yellow-200 dark:bg-yellow-500/30">and </mark> *<mark class="bg-yellow-200 dark:bg-yellow-500/30">asynchronous</mark>*<mark class="bg-yellow-200 dark:bg-yellow-500/30">.</mark> Synchronous callbacks are called immediately after the invocation of the outer function, while asynchronous callbacks are called at some point later, after an asynchronous operation has completed.

```javascript
let value = 1;

function doSomething(callback) {

// synchromous execution
 callback();

// asynchronous execution
setTimeout(callback,0);
}

doSomething(() => {
  value = 2;
});
console.log(value); // 1 or 2?
```

Here , in this example the `callback` is executed `synchronously` and the `output` will be `2`.

> Note - Examples of synchronous callbacks include the callbacks passed to [`Array.prototype.map`](http://Array.prototype.map)[`()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map), [`Array.prototype.forEach()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach), etc. Examples of asynchronous callbacks include the callbacks passed to [`setTimeout()`](https://developer.mozilla.org/en-US/docs/Web/API/Window/setTimeout) and [`Promise.prototype.then()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/then).

### Why callbacks are used in asynchronous programming

JavaScript executes code line by line (synchronously), but sometimes we need to wait for a task to complete . Many operations don't finish instantly like api call , timers, file reading and DB queries. Callbacks let you **continue execution without blocking**, and define *what should happen later*.

### Callback for async operation

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

setTimeout(function () {
    console.log("Inside setTimeout");
}, 2000);

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

*   setTimeout() is an asynchronous function that takes a callback to execute after 2 seconds.
    
*   The rest of the code continues executing without waiting.
    

### Callback usage in common scenarios

1.  **Handling Asynchronous Operations**  
    Callbacks are widely used in
    
    *   API requests (fetching data)
        
    *   Reading files (Node.js file system)
        
    *   Event listeners (clicks, keyboard inputs)
        
    *   Database queries (retrieving data)
        
2.  **Callbacks in Functions Handling Operations**  
    When a function needs to execute different behaviors based on input, callbacks make the function flexible.
    
    ```javascript
    function calc(a, b, callback) {
        return callback(a, b);
    }
    
    function add(x, y) {
        return x + y;
    }
    
    function mul(x, y) {
        return x * y;
    }
    
    console.log(calc(5, 3, add));    
    console.log(calc(5, 3, mul));
    
    // calculate() receives two numbers and a function (add or multiply).
    
    // The passed function is executed inside calculate().
    ```
    
3.  **Callbacks in Event Listeners**  
    JavaScript is event-driven, and callbacks handle user interactions like clicks and key presses.
    
    ```javascript
    document
    .getElementById("myButton")
    .addEventListener("click", function () {
        console.log("Button clicked!");
    });
    ```
    
4.  **Callbacks in API Calls (Fetching Data)**  
    Callbacks are useful when retrieving data from APIs.
    
    ```javascript
    function fetch(callback) {
        fetch("https://jsonplaceholder.typicode.com/todos/1")
            .then(response => response.json())
            .then(data => callback(data))
            .catch(error => console.error("Error:", error));
    }
    
    function handle(data) {
        console.log("Fetched Data:", data);
    }
    
    fetch(handle);
    ```
    

## **Problems with Callbacks**

Callbacks are powerful, but they come with some real pain points—especially as your app grows.

1.  **Callback Hell (Nested Callbacks)**
    
    ```javascript
    function step1(callback) {
        setTimeout(() => {
            console.log("Step 1 completed");
            callback();
        }, 1000);
    }
    
    function step2(callback) {
        setTimeout(() => {
            console.log("Step 2 completed");
            callback();
        }, 1000);
    }
    
    function step3(callback) {
        setTimeout(() => {
            console.log("Step 3 completed");
            callback();
        }, 1000);
    }
    
    step1(() => {
        step2(() => {
            step3(() => {
                console.log("All steps completed");
            });
        });
    });
    ```
    
    As the number of steps increases, the nesting grows deeper, making the code difficult to manage.
    
2.  **Error Handling Issues in Callbacks**
    
    ```javascript
    function divide(a, b, callback) {
        if (b === 0) {
            callback(new Error("Cannot divide by zero"), null);
        } else {
            callback(null, a / b);
        }
    }
    
    function result(error, result) {
        if (error) {
            console.log("Error:", error.message);
        } else {
            console.log("Result:", result);
        }
    }
    
    divide(10, 2, result);
    divide(10, 0, result);
    ```
    

The main pain-point to work with callback is the code readability . It is majorly affected by the callbacks and can become much difficult to use the callbacks.  
We can use the promises or async/await as the callbacks alternative.
