Pebellslearn by building
0%
RoadmapsMatrixCoursesSandboxSign in
Asynchronous JavaScript  ›  Lesson

Callbacks and Callback Hell

Callbacks 12 minA callback is a function handed to another function to be called later, once some work is done — the classic way to react to something async before Promises existed. Nesting callback inside callback to run steps in order produces callback hell, a staircase that's hard to read and hard to change.

Callbacks and Callback Hell

In short: a callback is a function you hand to another function, to be called later — often once some work finishes. It's how JavaScript reacted to things before Promise existed, and it still shows up everywhere (addEventListener, setTimeout, array methods). The trouble starts when several async steps must run in order: nesting a callback inside a callback inside a callback produces callback hell — a staircase of indentation that's hard to read and harder to change.

Left: orderCoffee("Asha", callback) — you walk away with a ticket, and the clerk calls callback(msg) when ready. Right: callback hell — step1 nesting step2 nesting step3 nesting deeper into "the pit", with a note that each step only knows how to start once the one above it calls back; the fix is the same shape Promises give you: chain steps instead of nesting them

Calling back once the work is done

A callback that runs synchronously, right when the work is ready:

javascript

onDone is the callback — a function processOrder calls once it has something to report. The caller decides what happens with the result; processOrder doesn't need to know or care.

A ticket you walk away with

Callbacks get more useful once the work actually takes time — you hand over a callback and move on, like leaving your name with a clerk:

javascript

orderCoffee returns immediately after placing the order — it doesn't block waiting for the coffee. The callback is called later, once the (simulated) work finishes, with the result. Wrapping the call in a Promise and await-ing it here is just so every line prints before this example ends — the pattern being shown is the plain callback itself.

Three steps, nested three levels deep

The problem callbacks create: running steps in order means nesting them, one inside the next.

javascript

Each step can only start once the one before it calls back, so the code has to nest to express that order — three steps, three levels deep. Real programs with five or six sequential async steps turn this into an unreadable staircase, sliding further right with every step, which is exactly the shape Promises (next lessons) were designed to flatten back out.

Quick practice

quick drill

What is a callback, in plain terms?

quick drill

Why does "callback hell" happen when you need several async steps in order?

quick drill

What is the main problem with deeply nested callbacks, beyond how they look?

Practice — level up

0/1 solved

Write your answer, then compare it with a rubric and a model answer.

ExplainWhy nesting three steps is a problem

Explain what makes step1(() => { step2(() => { step3(() => { console.log("done"); }); }); }); hard to work with as more steps get added, compared to a flatter alternative like a Promise chain.