Skip to main content

Command Palette

Search for a command to run...

Callbacks in JavaScript: Why They Exist

Updated
β€’3 min readβ€’View as Markdown
Callbacks in JavaScript: Why They Exist

Introduction

JavaScript is powerful because functions are first-class citizens β€” meaning they can be treated like values.

You can:

  • Store functions in variables

  • Pass functions as arguments

  • Return functions from other functions

This ability is what makes callbacks possible.

What is a Callback Function?

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

Basic Example

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

function processUserInput(callback) {
  const name = "Pratham";
  callback(name);
}

processUserInput(greet);

Here:

  • greet is the callback

  • processUserInput executes it

Functions as Values in JavaScript

Before understanding callbacks deeply, you need this concept:

function sayHello() {
  console.log("Hello!");
}

const fn = sayHello; // function assigned to variable
fn(); // Hello!

This shows:

  • Functions behave like normal variables

Passing Functions as Arguments

function executeTask(task) {
  console.log("Starting task...");
  task();
}

executeTask(function () {
  console.log("Task completed!");
});

πŸ‘‰ Output:

Starting task...
Task completed!

This is the core idea behind callbacks.

Why Callbacks Are Used (Async Programming)

JavaScript is single-threaded, but it handles async operations like:

  • API calls

  • File reading

  • Timers

πŸ‘‰ Instead of blocking execution, JavaScript uses callbacks.

Without Callback (Blocking Concept)

const data = getDataFromServer(); // imagine delay
console.log(data);

Problem:

  • Code waits β†’ bad performance

With Callback (Non-blocking)

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

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

Output after 2 seconds:

Data received

JS continues running while waiting

Common Callback Use Cases

1. Timers

setTimeout(() => {
  console.log("Runs after 2 seconds");
}, 2000);

2. Event Handling

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

3. API Calls (Old Way)

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

The Problem: Callback Nesting

When callbacks are nested inside callbacks β†’ code becomes messy.

Callback Hell Example

loginUser(function (user) {
  getUserData(user, function (data) {
    getOrders(data, function (orders) {
      console.log(orders);
    });
  });
});

Problems:

  • Hard to read

  • Hard to debug

  • Hard to maintain

Conceptual Understanding of the Problem

Think of it like:

β€œDo this β†’ then inside it do this β†’ then inside that do this…”

It creates a pyramid structure:

level 1
  level 2
    level 3
      level 4

This is called Callback Hell or Pyramid of Doom.

How It Was Solved Later

To fix callback problems, JavaScript introduced:

  • Promises

  • Async/Await

But callbacks are still important because:

  • They are the foundation of async JS

  • Many APIs still use them

Diagram Ideas

1. Function Flow

Main Function
   ↓
Calls Another Function (Callback)
   ↓
Callback Executes Later

2. Nested Callback Flow

loginUser()
  ↓
getUserData()
  ↓
getOrders()
  ↓
display()

Summary

  • Functions in JavaScript behave like values

  • Callbacks = functions passed into other functions

  • Used to handle async operations without blocking

  • Widely used in timers, events, APIs

  • Major drawback β†’ callback nesting (callback hell)

  • Later improved using Promises & async/await