Callbacks
A callback is simply a function you pass as an argument, expecting it to be called later — either immediately (synchronous) or at some point in the future (asynchronous).
Simple examples
// Async callback — runs after 1 second
setTimeout(() => {
console.log('fired!')
}, 1000)
// Sync callback — runs immediately for each element
const doubled = [1, 2, 3].map((n) => n * 2)
// Event callback — runs when the event occurs
button.addEventListener('click', function handleClick() {
console.log('clicked')
})
Callback Hell (Pyramid of Doom)
When you chain multiple async operations that each depend on the previous result, you nest callbacks inside callbacks:
getUser(id, (user) => {
getOrders(user.id, (orders) => {
getOrderDetails(orders[0].id, (details) => {
getItems(details.itemId, (items) => {
// four levels deep and growing…
})
})
})
})
This gets hard to read, hard to debug, and hard to handle errors (you'd need a try/catch or error callback at every level).
This is exactly why Promises were introduced
Promises flatten the chain. async/await makes it look synchronous. See Asynchronous.
Related
Event Loop — how callbacks are scheduled behind the scenes
Asynchronous — Promises & async/await as the modern alternative