Now that we understand what async JavaScript is and why it is needed, let's dive into how JavaScript handles asynchronous operations.
A callback function is a function passed as an argument to another function and executed later, typically after an asynchronous task is completed.
setTimeout
function greet(name, callback) {
console.log(`Hello, ${name}!`);
callback();
}
function askQuestion() {
console.log("How are you?");
}
greet("Salman", askQuestion);
🔍 Output:
Hello, Salman!
How are you?
➡️ Here, askQuestion
is a callback function passed to greet
, ensuring that it runs after greeting.
function fetchData(callback) {
setTimeout(() => {
console.log("Data fetched successfully!");
callback();
}, 2000);
}
function processData() {
console.log("Processing the fetched data...");
}
fetchData(processData);
🔍 Output:
(Data fetches after 2 seconds)
Data fetched successfully!
Processing the fetched data...
➡️ processData
is called after fetchData
completes.
When multiple asynchronous tasks depend on each other, callbacks get deeply nested, making code hard to read and maintain.
function step1(callback) {
setTimeout(() => {
console.log("Step 1 completed");
callback();
}, 1000);
}
function step2(callback) {
setTimeout(() => {
console.log("Step 2 completed");
callback();
}, 1000);
}
function step3() {
setTimeout(() => {
console.log("Step 3 completed");
}, 1000);
}
// Callback Hell
step1(() => {
step2(() => {
step3();
});
});