Skip to main content

Command Palette

Search for a command to run...

Callbacks in JavaScript: Why They Exist

Updated
•4 min read•View as Markdown

Introduction

In JavaScript, functions are not just blocks of code — they are values.

This means you can:

  • Store them in variables

  • Pass them as arguments

  • Return them from other functions

This ability leads to an important concept:

Callbacks

Callbacks are especially important in asynchronous JavaScript and are the foundation for promises and async/await.


Functions as Values in JavaScript

Before understanding callbacks, we must understand that functions behave like values.

Example:

function greet() {
  console.log("Hello");
}

const sayHello = greet;

sayHello(); // Hello

Here:

  • The function is assigned to a variable

  • It is used just like a value


Passing Functions as Arguments

Functions can also be passed as arguments to other functions.

Example:

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

function done() {
  console.log("Done processing");
}

processUser("Manoj", done);

Output:

Processing user: Manoj
Done processing

What is a Callback Function?

A callback function is:

A function that is passed as an argument to another function and is executed later.

In the previous example:

  • done is a callback function

  • It is passed to processUser

  • It is executed inside that function


Why Callbacks Are Used

Callbacks are mainly used when:

  • The result of a task is not immediately available

  • We want to execute something after a task completes

This is especially useful in asynchronous programming.


Callback in Asynchronous JavaScript

Example using setTimeout:

console.log("Start");

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

console.log("End");

Output:

Start
End
Task completed

Explanation:

  • The function inside setTimeout is a callback

  • It runs after 2 seconds

  • JavaScript does not wait for it


Real-World Example

Imagine you ordered food online:

  • You place an order

  • The system processes it

  • When the food is ready, you get notified

The notification function is like a callback — it runs after the task is complete.


Common Use Cases of Callbacks

1. Event Handling

document.getElementById("btn").addEventListener("click", function () {
  console.log("Button clicked");
});
  • The function runs when the user clicks the button

2. API Calls (Older Approach)

function fetchData(callback) {
  setTimeout(() => {
    callback("Data received");
  }, 2000);
}

fetchData(function (data) {
  console.log(data);
});

3. Array Methods

const numbers = [1, 2, 3];

numbers.forEach(function (num) {
  console.log(num);
});
  • The function passed to forEach is a callback

Problem with Callbacks: Callback Nesting

When callbacks are used repeatedly inside each other, code becomes hard to read.

Example:

setTimeout(() => {
  console.log("Step 1");

  setTimeout(() => {
    console.log("Step 2");

    setTimeout(() => {
      console.log("Step 3");
    }, 1000);

  }, 1000);

}, 1000);

Problems:

  • Hard to read

  • Hard to debug

  • Difficult to maintain

This is often called:

Callback Hell


Visual Flow (Concept)

Simple Callback Flow

Main Function → Executes → Calls Callback → Callback Runs

Nested Callback Flow

Step 1
  ↓
Step 2
  ↓
Step 3

Common Mistakes

  • Calling the function instead of passing it

  • Forgetting that callbacks run later

  • Writing deeply nested callbacks


Interview Points

  • Functions are first-class citizens in JavaScript

  • Callbacks are functions passed as arguments

  • Used heavily in asynchronous programming

  • Callback hell is a common problem


Conclusion

Callbacks are one of the most fundamental concepts in JavaScript:

  • They allow flexible and dynamic execution

  • They enable asynchronous behavior

  • But excessive nesting makes code difficult to manage

To solve these problems, JavaScript introduced:

  • Promises

  • Async/Await