A JavaScript callback is a function passed as an argument into another function so it can be called back at the right time. Callbacks power synchronous array utilities like map() and filter(), DOM event listeners, and asynchronous operations.
flowchart LR
Sync["Sync: items.map(fn)"] --> RunNow["fn runs immediately before map returns"]
Async["Async: setTimeout(fn, 100)"] --> Queue["Registered, current stack finishes first, then fn runs"]
[1, 2].map(x => x * 2)).In older Node.js APIs, async callbacks follow the (error, result) convention where error is null on success. Today, modern APIs wrap callbacks in Promises so callers can use async/await cleanly instead of nesting five levels deep ("callback hell").
// Higher-order function accepting a callback
function processOrders(orders, onItemProcessed) {
const results = [];
for (const order of orders) {
const withFee = { ...order, total: order.amount + 2 };
onItemProcessed(withFee);
results.push(withFee);
}
return results;
}
const processed = processOrders(
[{ id: 1, amount: 20 }, { id: 2, amount: 45 }],
(order) => console.log(`Processed #${order.id}: $${order.total}`)
);
console.log("Count:", processed.length);
button.addEventListener("click", saveForm()) executes saveForm immediately on page load. Pass the function reference saveForm without ().new Promise(...) or use async/await.onDone() when the caller omitted it throws TypeError; invoke safely with onDone?.(result).Callback hell (also called the "pyramid of doom") happens when multiple sequential async tasks nest callbacks inside callbacks, duplicating error checks at every level. Promises and async/await flatten that code into readable top-to-bottom steps.
No, array methods (forEach, map, filter, sort) run their callbacks synchronously before returning.
Wrap it in new Promise((resolve, reject) => oldFn(arg, (err, res) => err ? reject(err) : resolve(res))), or use util.promisify in Node.js.
Sign in to track your learning journey, earn industry-recognized certificates, and join our elite developer community.
Quick Access With
Experiment with the code from this lesson in our interactive playground.