JS Async Callbacks
In this page:
function functionName(callback) {
// async work
callback(result);
}
functionName(function(result) {
// use result
});
What a Callback Is
A callback is nothing more than a regular function passed as an argument to another function -- the receiving function calls it back at some later point, often once an asynchronous operation (like a timer or a network request) finishes.
उदाहरण: What a Callback Is
// Define the function `greet` taking `name`, `callback`
// Define the function `greet` taking `name`, `callback`
function greet(name, callback) {
// Call `callback(`Hello, ${name}`)`
// Call `callback(`Hello, ${name}`)`
callback(`Hello, ${name}`);
}
// Call `greet("Sam", (message) => console.log(message))`
// Call `greet("Sam", (message) => console.log(message))`
greet("Sam", (message) => console.log(message));
Callbacks with Asynchronous Operations
The classic use of a callback is pairing it with something that takes time -- setTimeout(callback, delay) calls the callback after the delay elapses, and older AJAX APIs used callbacks to run code once a network response arrived, since there was no other way to react to something happening "later".
उदाहरण: Callbacks with Asynchronous Operations
setTimeout(() => console.log("Runs later"), 500);
// Older AJAX used callbacks similarly, run once a response arrives
The Error-First Callback Convention
A widely-adopted convention, especially in Node.js-style code, is the "error-first" callback: callback(error, result), where the first argument is either an Error object (if something went wrong) or null (if it succeeded) -- checking that first argument becomes the standard way to handle failure in callback-based code.
उदाहरण: The Error-First Callback Convention
// Define the function `loadData` taking `callback`
// Define the function `loadData` taking `callback`
function loadData(callback) {
// Call `setTimeout(() => callback(null, { id: 1 }), 100)`
// Call `setTimeout(() => callback(null, { id: 1 }), 100)`
setTimeout(() => callback(null, { id: 1 }), 100);
}
loadData((error, result) => {
if (error) console.log("Failed:", error);
else console.log("Success:", result);
});
The Problem: Callback Hell
When several asynchronous steps must happen in sequence, each depending on the previous one's result, callback-based code nests deeper and deeper -- a pattern commonly called 'callback hell' or 'the pyramid of doom', which becomes genuinely hard to read, modify, and debug as more steps are added.
उदाहरण: The Problem: Callback Hell
function step1(cb) { setTimeout(() => cb(1), 10); }
function step2(a, cb) { setTimeout(() => cb(a + 1), 10); }
function step3(b, cb) { setTimeout(() => cb(b + 1), 10); }
step1((a) => {
step2(a, (b) => {
step3(b, (c) => console.log("Deeply nested result:", c)); // callback hell
});
});
Callbacks Still in Use Today
Despite Promises and async/await being preferred for most sequential async logic, plain callbacks remain common and appropriate for certain patterns -- event listeners (addEventListener), array iteration methods (forEach, map), and any 'run this every time X happens' scenario that is not really about a single eventual result.
उदाहरण: Callbacks Still in Use Today
document.addEventListener("click", () => console.log("Clicked")); // still a normal, appropriate callback use
[1, 2, 3].forEach(n => console.log(n)); // another normal callback use
Chapter Quiz — Complete all 26 topics to unlock
0/26 topics done
Complete these topics first:
- JS Dates
- JS Math
- JS Conditionals
- JS Switch
- JS Loop For
- JS Loop While
- JS Iterables
- JS Sets
- JS Maps
- JS typeof
- JS Type Conversion
- JS Destructuring
- JS Arrow Functions
- JS Classes
- JS Modules
- JS Promises
- JS Async/Await
- JS DOM
- JS DOM Methods
- JS Events Advanced
- JS DOM Navigation
- JS DOM Collections
- JS Async Callbacks
- JS Async Parallel
- JS Date Set
- JS Set Logic