Callback Functions
Functions passed as arguments. The foundation of async JavaScript.
What Are Callbacks?
A function passed to another function to be called later.
function greet(name, callback) {
const message = "Hello, " + name;
callback(message);
}
function log(text) {
console.log(text);
}
greet("Alice", log);
// "Hello, Alice"'log' is passed as a callback. greet() calls it when the message is ready.
1 / 2
Synchronous Callbacks
Executed immediately within the calling function.
// Array methods use sync callbacks: const nums = [1, 2, 3, 4, 5]; nums.forEach((n) => console.log(n)); // logs each nums.map((n) => n * 2); // [2, 4, 6, 8, 10] nums.filter((n) => n > 3); // [4, 5] nums.find((n) => n === 3); // 3 nums.sort((a, b) => a - b); // sorted
// .filter() with a callback:
"apple""banana""cherry"
Async Callbacks
Executed later, when an operation completes.
// setTimeout — callback runs after delay:
setTimeout(() => {
console.log("2 seconds passed!");
}, 2000);
// Event listener — callback runs on event:
button.addEventListener("click", () => {
console.log("Clicked!");
});
// File reading (Node.js):
fs.readFile("data.txt", (err, data) => {
console.log(data);
});// setTimeout demo:
Error-First Pattern
Node.js convention: first parameter is always the error.
// Error-first callback pattern:
fs.readFile("data.txt", (err, data) => {
if (err) {
console.error("Failed:", err.message);
return;
}
console.log("Got:", data);
});
// Creating your own:
function fetchUser(id, callback) {
if (!id) {
callback(new Error("ID required"), null);
return;
}
// ... fetch logic
callback(null, userData); // success: err=null
}Convention rules:
- First parameter is always
err(or null on success) - Always check err before using data
- Return early after handling error to avoid running success code
Callback Hell
Nested callbacks make code hard to read and maintain.
✗ Callback hell
getUser(id, (err, user) => {
getPosts(user.id, (err, posts) => {
getComments(posts[0], (err, comments) => {
render(comments, (err) => {
// 😵 deeply nested
});
});
});
});✓ Modern alternative (Promises)
// Flat and readable: const user = await getUser(id); const posts = await getPosts(user.id); const comments = await getComments(posts[0]); await render(comments);
💡 Callbacks are still fundamental to understand, but modern JavaScript uses Promises and async/await for cleaner async code.
FAQ
Common questions about callbacks.