Skip to main content

Callbacks in JavaScript: Why They Exist

Updated 6 min readMarkdown

Callback functions are one of the most important concepts in JavaScript.

At first, they look strange.

Beginners usually see something like:

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

and immediately wonder:

“Why is a function sitting inside another function?”

Then callbacks start appearing everywhere:

  • event listeners

  • API requests

  • timers

  • array methods

  • asynchronous code

Understanding callbacks properly is extremely important because JavaScript heavily relies on functions being passed around.

The good news?

The core idea is actually simple.


Functions Are Values in JavaScript

In JavaScript, functions are treated like values.

That means functions can:

  • be stored in variables

  • be passed as arguments

  • be returned from other functions

Example:

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

const sayHi = greet;

sayHi();

Output:

Hello

The function was assigned like a normal value.

This ability is the foundation of callbacks.


Passing Functions as Arguments

Since functions are values, we can pass them into other functions.

Example:

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

function processUser(callback) {
  callback("Gagan");
}

processUser(greet);

Output:

Hello Gagan

Here:

greet

was passed into:

processUser()

as an argument.


What Is a Callback Function?

A callback function is simply:

A function passed into another function to be executed later.

Example:

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

function performTask(callback) {
  console.log("Performing task...");

  callback();
}

performTask(showMessage);

Output:

Performing task...
Task completed

Here:

showMessage

is the callback function.


Diagram: Function Calling Another Function

performTask()
      ↓
Receives callback function
      ↓
callback() executes

Why Are Callbacks Useful?

Callbacks allow one function to decide:

What should happen next

without hardcoding behavior.

This makes programs flexible and reusable.

Example:

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

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

function multiply(x, y) {
  return x * y;
}

console.log(calculate(2, 3, add));
console.log(calculate(2, 3, multiply));

Output:

5
6

Same function.

Different behavior using callbacks.


Callback Functions in Array Methods

Callbacks are heavily used in JavaScript array methods.

Example:

const numbers = [1, 2, 3];

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

Here:

function(num) {
  console.log(num);
}

is a callback.

The array method decides:

  • when to call it

  • how many times to call it

  • what values to pass


Common Places Where Callbacks Are Used

Callbacks appear everywhere in JavaScript.

Examples include:

  • Event listeners

  • Timers

  • API requests

  • File handling

  • Array methods

  • Database operations


Example: Event Listener Callback

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

The callback runs only when:

click event happens

Example: Timer Callback

setTimeout(function() {
  console.log("Executed after 2 seconds");
}, 2000);

The callback runs later.

Not immediately.


Why Callbacks Matter in Asynchronous Programming

JavaScript is single-threaded.

That means:

One thing executes at a time

But many operations take time.

Examples:

  • API requests

  • Database queries

  • File reading

  • Timers

If JavaScript waited for every slow operation to finish, applications would freeze constantly.

Callbacks solve this problem.


Synchronous vs Asynchronous Behavior

Synchronous Code

console.log("Start");
console.log("Middle");
console.log("End");

Output:

Start
Middle
End

Everything executes line by line.


Asynchronous Example with Callback

console.log("Start");

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

console.log("End");

Output:

Start
End
Inside callback

Why?

Because:

setTimeout does not block execution

JavaScript continues running other code.

The callback executes later.


Mental Model of Async Callbacks

Start async task
       ↓
Continue executing other code
       ↓
Task finishes later
       ↓
Callback executes

Real-World Analogy

Imagine ordering food.

You do not:

Stand frozen at counter for 20 minutes

Instead:

  • order food

  • continue talking

  • eat later when food arrives

The callback is basically:

“Call me when ready”

Callback Usage in API Requests

Older JavaScript code heavily used callbacks for API requests.

Example:

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

Meaning:

Run this function when data arrives

The Problem with Nested Callbacks

Callbacks are useful.

But excessive nesting becomes difficult to manage.

Example:

loginUser(function(user) {

  getProfile(user.id, function(profile) {

    getPosts(profile.id, function(posts) {

      console.log(posts);

    });

  });

});

This structure becomes hard to:

  • read

  • debug

  • maintain

  • handle errors in

This is commonly called:

Callback Hell

or:

Pyramid of Doom

because the code starts drifting rightward like a collapsing staircase.


Diagram: Nested Callback Flow

Task 1
  ↓
Callback 1
  ↓
Task 2
  ↓
Callback 2
  ↓
Task 3
  ↓
Callback 3

Why Callback Nesting Becomes a Problem

Nested callbacks create:

  • messy structure

  • poor readability

  • difficult error handling

  • maintenance nightmares

This problem eventually led to:

  • Promises

  • async/await

which simplify asynchronous code.


Important Beginner Misconception

Some beginners think:

“Callbacks are only for async programming.”

Wrong.

Callbacks are simply:

Functions passed into other functions

Asynchronous programming is just one major use case.

Even this is a callback:

numbers.map(num => num * 2);

Practical Mental Model

Callback

Function passed to another function

Async Callback

Run this function later when task completes

Simple Rule to Remember

Whenever you see:

someFunction(anotherFunction)

there is a high chance:

anotherFunction is a callback

Common Beginner Mistake

People often write:

setTimeout(callback(), 1000);

instead of:

setTimeout(callback, 1000);

Why wrong?

Because:

callback()

executes immediately.

But:

callback

passes the function itself.

This tiny difference causes massive beginner confusion.


Final Mental Shortcut

Callbacks are basically:

“Here is a function.
Run it later when needed.”

That is the entire concept.


Conclusion

Callback functions are functions passed into other functions to be executed later.

They are possible because JavaScript treats functions as values.

Callbacks are heavily used in:

  • asynchronous programming

  • timers

  • event handling

  • array methods

  • API operations

They help JavaScript perform non-blocking operations efficiently.

However, deeply nested callbacks can become difficult to manage, leading to callback hell.

Understanding callbacks properly is important because they form the foundation for more advanced concepts like:

  • Promises

  • async/await

  • event-driven programming

The core mental model is simple:

Pass a function now.
Execute it later.

That idea powers a huge portion of JavaScript.

1 view

No comments yet. Be the first to comment.