JavaScript Tutorial
Master callback functions for event handling and asynchronous programming.
Why this matters
Callbacks are fundamental to JavaScript. They enable event handling, asynchronous operations, and functional programming patterns essential to modern web development.
What are Callback Functions?
A callback function is a function passed as an argument to another function. The receiving function can call the callback to perform some action, often after an event occurs or operation completes.
Callbacks are fundamental to JavaScript's event-driven and asynchronous nature.
Basic Callback Function
// Function that accepts a callback
function greet(name, callback) {
const greeting = "Hello, " + name;
callback(greeting);
}
// Callback function
function displayGreeting(message) {
console.log(message);
}
// Pass the callback function
greet("Alice", displayGreeting);
// Output: Hello, Alice
// Using anonymous function as callback
greet("Bob", function(message) {
console.log(">> " + message);
});
// Output: >> Hello, Bob
// Using arrow function as callback
greet("Charlie", (message) => console.log(message.toUpperCase()));
// Output: HELLO, CHARLIE
Callbacks are functions passed to other functions. They're called at specific times.
Event Listeners with Callbacks
Callbacks are heavily used for event handling. When an event occurs, the callback function is called.
Event Handlers
// HTML: <button id="myBtn">Click me</button>
const button = document.getElementById("myBtn");
// Click event with callback
button?.addEventListener("click", function() {
console.log("Button clicked!");
});
// Using arrow function
button?.addEventListener("click", () => {
console.log("Button clicked again!");
});
// Callback receives event object
button?.addEventListener("click", function(event) {
console.log("Click at:", event.clientX, event.clientY);
});
// Multiple event listeners
button?.addEventListener("mouseenter", () => console.log("Mouse entered"));
button?.addEventListener("mouseleave", () => console.log("Mouse left"));
addEventListener uses callbacks to respond to user events.
Array Methods with Callbacks
Array methods like map, filter, reduce, and forEach use callbacks to process elements.
Array Methods
const numbers = [1, 2, 3, 4, 5];
// map - transform each element
const doubled = numbers.map(function(num) {
return num * 2;
});
console.log(doubled); // [2, 4, 6, 8, 10]
// filter - keep elements that match condition
const evens = numbers.filter((num) => num % 2 === 0);
console.log(evens); // [2, 4]
// forEach - execute for each element
numbers.forEach((num, index) => {
console.log("Index " + index + ": " + num);
});
// reduce - accumulate into single value
const sum = numbers.reduce((acc, num) => acc + num, 0);
console.log(sum); // 15
// find - return first match
const firstEven = numbers.find((num) => num % 2 === 0);
console.log(firstEven); // 2
Array methods use callbacks to iterate and transform collections.
Asynchronous Callbacks
Callbacks are essential for asynchronous operations like timers, file reading, and API calls. The callback is called when the operation completes.
Asynchronous Operations
// setTimeout - run code after delay
setTimeout(function() {
console.log("This runs after 2 seconds");
}, 2000);
// setInterval - run code repeatedly
const id = setInterval(function() {
console.log("Repeat every 1 second");
}, 1000);
// Stop interval
setTimeout(() => clearInterval(id), 5000);
// Fetch API with callbacks
fetch("https://api.example.com/data")
.then(function(response) {
return response.json();
})
.then(function(data) {
console.log("Data:", data);
})
.catch(function(error) {
console.log("Error:", error);
});
// File operations (Node.js)
const fs = require("fs");
fs.readFile("file.txt", "utf8", function(err, data) {
if (err) {
console.log("Error:", err);
} else {
console.log("File content:", data);
}
});
Callbacks handle completion of asynchronous operations.
Callback Hell (Callback Pyramid of Doom)
When callbacks are deeply nested, code becomes hard to read. This is called 'callback hell' or 'callback pyramid of doom'.
Modern JavaScript provides Promises and async/await to handle this issue more elegantly.
Callback Hell and Solutions
// Callback Hell - deeply nested, hard to read
getUser(userId, function(err, user) {
if (err) {
console.log(err);
} else {
getOrders(user.id, function(err, orders) {
if (err) {
console.log(err);
} else {
getOrderDetails(orders[0].id, function(err, details) {
if (err) {
console.log(err);
} else {
console.log(details);
}
});
}
});
}
});
// Better: Using Promises
getUser(userId)
.then(user => getOrders(user.id))
.then(orders => getOrderDetails(orders[0].id))
.then(details => console.log(details))
.catch(err => console.log(err));
// Best: Using async/await
async function displayOrderDetails() {
try {
const user = await getUser(userId);
const orders = await getOrders(user.id);
const details = await getOrderDetails(orders[0].id);
console.log(details);
} catch (err) {
console.log(err);
}
}
Callbacks can lead to hard-to-read code. Use Promises or async/await for cleaner asynchronous code.
Common Mistakes
- Forgetting to pass the callback function: Pass the function itself, not the result of calling it. Use 'callback' not 'callback()'.
- Not handling errors in callbacks: Always check for errors, especially in asynchronous callbacks. Use try/catch or .catch().
- Callback hell from excessive nesting: Use Promises or async/await instead of deeply nested callbacks for better readability.
FAQ
What is a callback function?
A callback function is a function passed as an argument to another function. It's called after some event occurs or operation completes.
When are callbacks used?
Callbacks are used for event handling, array iteration, asynchronous operations (timers, API calls, file operations), and more.
What is callback hell?
Callback hell occurs when callbacks are deeply nested, making code hard to read. Use Promises or async/await to avoid this.
How are callbacks different from Promises?
Callbacks are functions passed to other functions. Promises are objects representing eventual completion. Promises provide better error handling and readability.
Related Topics