Skip to main content

Command Palette

Search for a command to run...

Callbacks in JavaScript: Why They Exist

Updated
5 min readView as Markdown
Callbacks in JavaScript: Why They Exist
N

I build clean and simple web experiences and learn something new every day.

If you’ve been learning JavaScript, you’ve definitely seen this word callback

And at first it feels like:

Okay… it’s a function… but why is it passed inside another function???

And then when async comes in, it gets even more confusing. So in this blog, I’m going to break it down from zero to clear understanding no confusion, no heavy jargon. Just simple logic.


Functions in JavaScript Are Not “Special”

Before we even talk about callbacks, you need to understand one thing. In JavaScript, functions are just values. Yes, just like: numbers, strings, arrays.

Functions can also be stored in variables, passed as arguments, returned from other functions

Let me show you.

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

const greet = sayHello;

greet(); // Hello

We didn’t call sayHello() directly. We stored it in a variable and called it later. That’s because functions are treated like values.


Now Let’s Build the Idea of Callback

Now imagine this:

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

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

processUserInput(greet);

Look carefully. We passed greet as an argument. And then inside another function, it was called. This is a callback.


So What Exactly Is a Callback?

Let me say it in the simplest way: A callback is a function passed into another function to be called later. That’s it, nothing complicated.


Think About It Like This

Imagine you tell your friend:

Call me when you reach home.

You didn’t call them. You gave them a function (instruction) to execute later. That’s a callback.

Main Function => receives another function => executes it later


Why Do Callbacks Even Exist?

Now comes the real question. Why do we even need callbacks?

The answer is simple: Because of asynchronous JavaScript.


Let’s Understand With a Real Problem

Imagine this:

console.log("Start");

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

console.log("End");

Output:

Start
End
Data received

Now think. The data comes after 2 seconds. So how do we run code after the data is ready? We use a callback.


Callback Solves This Problem

function fetchData(callback) {
  setTimeout(() => {
    const data = "User Data";
    callback(data);
  }, 2000);
}

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

fetchData(displayData);

Here’s what’s happening: fetchData starts async work, after 2 seconds, it gets data, then it calls the callback. This ensures the code runs at the right time


This Is the Core Idea

Callbacks allow you to say:

Run this function AFTER something is done.


Common Places You Already Use Callbacks

Even if you didn’t realize, you’re already using callbacks.

1. setTimeout

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

That arrow function is a callback.

2. Event Listeners

button.addEventListener("click", () => {
 console.log("Clicked!"); 
});

That function runs only when the event happens.

Callback.

3. Array Methods

const numbers = [1, 2, 3];

numbers.forEach((num) => {
 console.log(num); 
});

The function inside forEach is also a callback.


Now Comes the Problem…

Callbacks are powerful. But they can get messy. Let’s see how.


Callback Nesting (Callback Hell)

Imagine this:

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

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

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

  }, 1000);

}, 1000);

Now look at this structure.

Step 1
   ↓
  Step 2
     ↓
    Step 3

The code keeps going deeper and deeper. This is called: Callback Hell


Why Callback Hell Is a Problem

  • Hard to read

  • Hard to debug

  • Hard to maintain

You lose track of logic.


Visualizing Nested Callbacks

Task 1
  └── Task 2
        └── Task 3
              └── Task 4

Looks messy, right? That’s the problem.


So What Did Developers Do?

Callbacks solved async problems… But created readability problems.So developers introduced Promises, Async/Await. But callbacks are still important. Because everything async in JS is built on top of callbacks.


One Simple Way to Think About Callbacks

Whenever you see a callback, just think: “This function will run later.”

That’s it.


Small Practice Example

Try this:

function greetUser(name, callback) {
  console.log("Hi " + name);
  callback();
}

function sayBye() {
  console.log("Bye!");
}

greetUser("Nausheen", sayBye);

Output:

Hi Nausheen
Bye!

Final Thoughts

Callbacks might feel confusing at first… But once you understand this - Functions can be passed like values, they can be executed later, they help handle async tasks. Everything becomes clear.


Key Takeaway

  • Callback = function passed into another function

  • Used to run code later

  • Very common in async JavaScript

  • Can become messy when nested

And honestly…
Once callbacks click, understanding Promises and Async/Await becomes 10x easier.

More from this blog

C

codeXninjaDev

54 posts

I build clean and simple web experiences and learn something new every day.