Skip to main content

Command Palette

Search for a command to run...

Callbacks in JavaScript: Why They Exist

Updated
7 min readView as Markdown

One of the most important ideas in JavaScript is:

Functions are treated like values.

This may sound simple, but it unlocks powerful programming patterns — including callbacks.

Callbacks are everywhere in JavaScript:

  • Event listeners

  • API requests

  • Timers

  • Array methods

  • File handling

  • Asynchronous programming

But many beginners first encounter callbacks and think:

“Why are functions being passed around like variables?”

In this blog, you’ll learn:

  • What callback functions are

  • Why callbacks exist

  • How functions can be passed as arguments

  • Common callback use cases

  • Why callback nesting becomes difficult


Functions Are Values in JavaScript

In JavaScript:

  • Functions are not special locked objects

  • They can be stored in variables

  • Passed to other functions

  • Returned from functions

This is the foundation of callbacks.


Example: Function Stored in Variable

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

greet();

Here:

  • The function is stored inside greet

Passing Functions as Arguments

Functions can also be passed into other functions.


Example

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

function execute(fn) {
  fn();
}

execute(sayHello);

Output

Hello

What Happened Here?

  • sayHello is passed into execute

  • execute runs the function using fn()

The passed function is called:

A callback function


What Is a Callback Function?

A callback is:

A function passed into another function to be executed later.


Simple Callback Structure

Function A
   ↓
passes function
   ↓
Function B executes it later

Real-Life Analogy

Imagine ordering food at a restaurant.

You say:

“Call me when the food is ready.”

You provide:

  • A callback action

The restaurant executes it later.

Callbacks work similarly.


Why Do Callbacks Exist?

Callbacks exist because many tasks take time.

Examples:

  • Fetching data from the internet

  • Reading files

  • Waiting for user clicks

  • Timers

JavaScript cannot stop the entire application while waiting.

Instead:

  • It continues running other code

  • Then executes a callback later


Understanding the Problem

Imagine this situation:

console.log("Start");

setTimeout(() => {
  console.log("Finished");
}, 2000);

console.log("End");

Output

Start
End
Finished

Notice:

  • JavaScript does not wait for setTimeout

  • It continues executing

The callback runs later.


Why This Matters

Without callbacks:

  • JavaScript would freeze while waiting

Callbacks allow JavaScript to stay responsive.

This is extremely important for:

  • Browsers

  • User interfaces

  • Servers


Callback Flow Diagram

Main Code Starts
       ↓
Async Task Begins
       ↓
JavaScript Continues Running
       ↓
Task Completes
       ↓
Callback Executes

Passing Functions as Arguments (Deep Understanding)

Let’s slow down and understand this clearly.


Example

function greet(name) {
  console.log(`Hello ${name}`);
}

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

processUser(greet);

Step-by-Step

Step 1

greet function exists.


Step 2

processUser(greet) passes the function.


Step 3

Inside processUser:

callback("Alex");

runs:

  • greet("Alex")

Output

Hello Alex

Common Callback Usage in JavaScript

Callbacks appear everywhere.


1. setTimeout()

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

The callback runs after 1 second.


2. Event Listeners

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

The callback runs:

  • When the user clicks

3. Array Methods

let numbers = [1, 2, 3];

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

Here:

  • num => num * 2 is a callback.

4. API Requests

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

The callback executes:

  • After data arrives

Why Asynchronous Programming Needs Callbacks

JavaScript is single-threaded.

That means:

  • One main task executes at a time

If JavaScript waited for every slow operation:

  • Applications would become unusable

Callbacks solve this problem.


Example Without Async Thinking

Imagine downloading data from the internet.

If JavaScript paused completely:

  • The webpage would freeze

  • Buttons would stop working

  • Animations would stop

Callbacks allow JavaScript to continue running smoothly.


Visual Async Example

Request Data
      ↓
Continue Running Code
      ↓
Data Arrives
      ↓
Run Callback

Callback Nesting Problem

Callbacks are useful…

But too many nested callbacks become difficult to manage.


Example of Nested Callbacks

loginUser(function(user) {

  getProfile(user, function(profile) {

    getPosts(profile, function(posts) {

      console.log(posts);

    });

  });

});

This quickly becomes messy.


Why Nested Callbacks Become Difficult

Problems include:

  • Harder readability

  • Deep indentation

  • Difficult debugging

  • Error handling complexity

This problem became known as:

Callback Hell


Nested Callback Flow Diagram

Login User
    ↓
Get Profile
    ↓
Get Posts
    ↓
Display Posts

Each step waits for the previous callback.


Callback Hell Visualization

Callback
   └── Callback
         └── Callback
               └── Callback

The code keeps moving deeper to the right.


Important Beginner Clarification

Callbacks themselves are NOT bad.

They were extremely important in early JavaScript.

Modern JavaScript later introduced:

  • Promises

  • async/await

to improve readability.

But callbacks are still everywhere.


Why Learning Callbacks Still Matters

Even modern JavaScript uses callbacks in:

  • Event listeners

  • Array methods

  • Timers

  • Browser APIs

Callbacks are foundational JavaScript knowledge.


Beginner-Friendly Mental Model

The simplest way to understand callbacks:

“Run this function later.”

That’s the core idea.


Common Beginner Mistakes

Passing vs Calling a Function

Wrong:

execute(greet());

This executes immediately.


Correct

execute(greet);

This passes the function itself.


Forgetting That Functions Are Values

Functions behave like variables in JavaScript.

This is what makes callbacks possible.


Real-World Use Cases

Callbacks are heavily used in:

  • Frontend interactions

  • API handling

  • Backend systems

  • Node.js

  • Timers

  • User events

Understanding callbacks is a major milestone in learning JavaScript.


Practice Exercises

Exercise 1

Create a function:

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

Pass it into another function.


Exercise 2

Use setTimeout() with a callback.


Exercise 3

Use map() with a callback function.


Final Thoughts

Callbacks exist because JavaScript needs a way to:

  • Run code later

  • Handle asynchronous operations

  • Keep applications responsive

The key ideas are:

Concept Meaning
Callback Function passed into another function
Async Programming Tasks happening later
Callback Purpose Execute code after something finishes

Callbacks may feel unusual initially, but they are one of the core ideas that make JavaScript powerful and interactive.

Once you understand callbacks, concepts like:

  • Promises

  • async/await

  • Event handling

become much easier to learn.