A callback function is a function that is passed as an argument to another function and is executed after some operation is completed. Callback functions allow you to write asynchronous code in JavaScript, meaning certain tasks can run in the background while other code continues to execute.
- Passed as Arguments: A callback is passed to another function as a parameter.
- Executed Later: It is called (or "called back") after a specific task is completed.
- Function as First-Class Citizen: Since JavaScript treats functions as first-class citizens, they can be passed as arguments to other functions.
Callbacks are commonly used for:
- Asynchronous operations like fetching data from a server, reading files, or waiting for a timer to complete.
- Customizing behavior by allowing users to provide their own functions.
Here is a basic example to illustrate how callback functions work:
function greet(name, callback) {
console.log(`Hello, ${name}!`);
callback();
}
function sayGoodbye() {
console.log("Goodbye!");
}
// Passing sayGoodbye as a callback
greet("Alice", sayGoodbye);
// Output:
// Hello, Alice!
// Goodbye!
console.log("Start");
setTimeout(() => {
console.log("This runs after 2 seconds");
}, 2000);
console.log("End");
// Output:
// Start
// End
// This runs after 2 seconds
function fetchData(callback) {
console.log("Fetching data...");
setTimeout(() => {
console.log("Data fetched successfully!");
callback();
}, 3000);
}
fetchData(() => {
console.log("Processing the fetched data.");
});
// Output:
// Fetching data...
// Data fetched successfully!
// Processing the fetched data.
Callback Function | Regular Function |
---|---|
Passed as an argument to another function | Called directly when needed |
Executed by the containing function | Executed immediately when invoked |
Used for asynchronous or custom behavior | Used for normal tasks |
While callbacks are very useful, they can sometimes lead to callback hell when there are multiple nested callbacks, making the code hard to read and debug.
setTimeout(() => {
console.log("Step 1 completed");
setTimeout(() => {
console.log("Step 2 completed");
setTimeout(() => {
console.log("Step 3 completed");
}, 1000);
}, 1000);
}, 1000);
To overcome callback hell, JavaScript introduced Promises and later async/await, which make asynchronous code cleaner and easier to manage.
function fetchData() {
return new Promise((resolve) => {
setTimeout(() => {
console.log("Data fetched successfully!");
resolve();
}, 3000);
});
}
fetchData().then(() => {
console.log("Processing the fetched data.");
});
async function fetchDataAsync() {
console.log("Fetching data...");
await new Promise((resolve) => {
setTimeout(() => {
console.log("Data fetched successfully!");
resolve();
}, 3000);
});
console.log("Processing the fetched data.");
}
fetchDataAsync();
// Output:
// Fetching data...
// Data fetched successfully!
// Processing the fetched data.
- A callback function is a function passed as an argument and executed later.
- Useful for asynchronous tasks like fetching data or timers.
- Can lead to callback hell if not managed well.
- Promises and async/await provide cleaner alternatives to callbacks in many cases.