Callback Functions
- This lesson explains how callback functions work in JavaScript.
Introduction to Callback Functions
JavaScript is a single-threaded language, but it can still handle time-consuming tasks such as:
Fetching data from a server
Reading files
Timers and delays
Event handling
To manage such tasks without blocking the main thread, JavaScript uses callbacks.
In this lesson, we will understand:
What callbacks are
Why callbacks are needed
Callback hell and its problems
Callbacks
What Is a Callback Function ?
A callback function is a function that is passed as an argument to another function and is executed later, after a task is completed.
Simple Definition
A callback is a function that runs after another function finishes its work.
Why Are Callbacks Needed ?
Some operations take time:
API requests
File loading
Timers
Database queries
If JavaScript waited synchronously:
UI would freeze
Page would stop responding
Callbacks allow JavaScript to:
Start a task
Continue other work
Execute callback when task finishes
JavaScript Callback Function Example
This code demonstrates the use of a callback function where sayBye is executed after the greet function completes.
function greet(name, callback) {
console.log("Hello " + name);
callback();
}
function sayBye() {
console.log("Goodbye");
}
greet("Rahul", sayBye);
How This Works
greet() is called
sayBye is passed as a callback
callback() executes after greeting
JavaScript Asynchronous Callback Handling
This code shows how a callback is used to process data after an asynchronous operation like setTimeout completes.
function fetchData(callback) {
setTimeout(() => {
console.log("Data fetched");
callback();
}, 2000);
}
function processData() {
console.log("Processing data");
}
fetchData(processData);
Real-Life Analogy
You order food at a restaurant:
You place an order
You do other things
Restaurant calls you when food is ready
That “call” is a callback.
JavaScript setTimeout Basic Example
This code demonstrates how setTimeout is used to execute a function after a specified delay.
setTimeout
setTimeout(function () {
console.log("Executed after 2 seconds");
}, 2000);
JavaScript Event Listener Example
This code demonstrates how addEventListener is used to execute a function when a button is clicked.
Event Listeners
button.addEventListener("click", function () {
console.log("Button clicked");
});
The function runs only after the click event occurs.
Advantages of Callbacks
Enable asynchronous programming
Keep application responsive
Simple concept
Widely supported
Disadvantages of Callbacks
Hard to read when nested
Difficult to debug
Error handling becomes complex
This leads to the next topic.
Callback Hell
What Is Callback Hell ?
Callback Hell occurs when callbacks are nested inside callbacks, creating deeply indented and unreadable code.
It is also known as:
Pyramid of Doom
Callback Pyramid
JavaScript Callback Hell (Nested setTimeout)
This code demonstrates callback hell using nested setTimeout functions to execute steps sequentially with delays.
setTimeout(() => {
console.log("Step 1");
setTimeout(() => {
console.log("Step 2");
setTimeout(() => {
console.log("Step 3");
setTimeout(() => {
console.log("Step 4");
}, 1000);
}, 1000);
}, 1000);
}, 1000);
Problems with Callback Hell
Poor readability
Hard to maintain
Difficult error handling
Complex debugging
Not scalable
Problems with Callback Hell
Poor readability
Hard to maintain
Difficult error handling
Complex debugging
Not scalable
Visual Structure of Callback Hell
function() {
function() {
function() {
function() {
function() {
}
}
}
}
}
This structure is difficult to understand and modify.
Real-World Example (Login Flow)
login(user, () => {
getProfile(() => {
getOrders(() => {
processPayment(() => {
console.log("Done");
});
});
});
});
Each step depends on the previous one, creating deep nesting.
Why Callback Hell Is Dangerous
Small change breaks logic
Error handling must be repeated
Code becomes fragile
How Developers Avoid Callback Hell
Although callbacks are important, modern JavaScript prefers:
Named functions
Modular code
Promises
async/await
(These will be covered in upcoming lessons.)
JavaScript Multiple setTimeout Execution Order
This code demonstrates how multiple setTimeout functions run independently based on their delays.
function step1() {
console.log("Step 1");
}
function step2() {
console.log("Step 2");
}
setTimeout(step1, 1000);
setTimeout(step2, 2000);
Best Practices When Using Callbacks
Keep callbacks small
Avoid deep nesting
Use meaningful function names
Handle errors properly
Prefer modern async patterns
Common Mistakes
Calling callback immediately instead of passing it
Forgetting error handling
Creating deeply nested callbacks
Mixing sync and async logic