Async Programming
đ 21. What are callbacks in Node.js, and what is callback hell?â
Callback āĻšāϞ⧠āĻāĻŽāύ āĻāĻāĻāĻŋ function āϝā§āĻāĻžāĻā§ argument āĻšāĻŋāϏā§āĻŦā§ āĻ āύā§āϝ āĻāĻāĻāĻŋ function-āĻ pass āĻāϰāĻž āĻšāϝāĻŧ, āĻāĻŦāĻ āϏā§āĻ function āϤāĻžāϰ āĻāĻžāĻ āĻļā§āώ āĻāϰāĻžāϰ āĻĒāϰ⧠āĻāĻāĻŋāĻā§ execute āĻāϰā§āĨ¤ Node.js-āĻ āϝā§āĻšā§āϤ⧠āϏāĻŦāĻāĻŋāĻā§ asynchronous āĻāĻŦāĻ non-blocking, āϤāĻžāĻ callback āĻšāϞ⧠asynchronous operations handle āĻāϰāĻžāϰ āϏāĻŦāĻā§āϝāĻŧā§ āĻĒā§āϰāύ⧠āĻāĻŦāĻ āĻŽā§āϞāĻŋāĻ āĻĒāĻĻā§āϧāϤāĻŋāĨ¤
// āϏāĻšāĻ callback-āĻāϰ āĻāĻĻāĻžāĻšāϰāĻŖ
fs.readFile("file.txt", "utf8", function (err, data) {
console.log(data);
});
Callback Hell āĻā§?
āϝāĻāύ āĻāĻāĻāĻŋ asynchronous operation-āĻāϰ āĻĒāϰ⧠āĻāϰā§āĻāĻāĻŋ, āϤāĻžāϰāĻĒāϰ⧠āĻāϰā§āĻāĻāĻŋ â āĻāĻāĻžāĻŦā§ nested callbacks-āĻāϰ āϏā§āϤāϰ āĻŦāĻžāĻĄāĻŧāϤ⧠āĻĨāĻžāĻā§, āϤāĻāύ code āĻĻā§āĻāϤ⧠āĻāĻāĻāĻŋ āϤā§āϰāĻŋāĻā§āĻā§āϰ āĻŽāϤ⧠āĻĄāĻžāύāĻĻāĻŋāĻā§ āĻšā§āϞ⧠āϝāĻžāϝāĻŧāĨ¤ āĻāĻāĻžāĻā§āĻ Callback Hell āĻŦāĻž Pyramid of Doom āĻŦāϞāĻž āĻšāϝāĻŧāĨ¤
// Callback Hell-āĻāϰ āĻāĻĻāĻžāĻšāϰāĻŖ
getUser(userId, function (err, user) {
getOrders(user.id, function (err, orders) {
getOrderDetails(orders[0].id, function (err, details) {
sendEmail(details, function (err, result) {
// āĻāϰ⧠nested āĻšāϤ⧠āĻĨāĻžāĻā§...
});
});
});
});
āĻāϤ⧠code āĻĒāĻĄāĻŧāĻž, maintain āĻāϰāĻž āĻāĻŦāĻ debug āĻāϰāĻž āĻ āϤā§āϝāύā§āϤ āĻāĻ āĻŋāύ āĻšāϝāĻŧā§ āĻĒāĻĄāĻŧā§āĨ¤
đĄ How do you avoid callback hell using Promises or async/await?â
ā§§. Promises āĻĻāĻŋāϝāĻŧā§
Promise āĻšāϞ⧠āĻāĻāĻāĻŋ object āϝā§āĻāĻŋ āĻāĻāĻāĻŋ asynchronous operation-āĻāϰ eventual completion āĻŦāĻž failure-āĻā§ represent āĻāϰā§āĨ¤ āĻāĻāĻŋāϰ āϤāĻŋāύāĻāĻŋ state āĻĨāĻžāĻā§: pending, fulfilled, āĻāĻŦāĻ rejectedāĨ¤
// Promise chain āĻĻāĻŋāϝāĻŧā§ Callback Hell āĻāĻĄāĻŧāĻž āύā§
getUser(userId)
.then((user) => getOrders(user.id))
.then((orders) => getOrderDetails(orders[0].id))
.then((details) => sendEmail(details))
.catch((err) => console.error(err)); // centralized error handling
āĻāϤ⧠code flat āĻĨāĻžāĻā§ āĻāĻŦāĻ āĻĒāĻĄāĻŧāϤ⧠āϏāĻšāĻ āĻšāϝāĻŧāĨ¤
⧍. async/await āĻĻāĻŋāϝāĻŧā§
async/await āĻšāϞ⧠Promises-āĻāϰāĻ syntactic sugar, āϝāĻž asynchronous code-āĻā§ synchronous-āĻāϰ āĻŽāϤ⧠āĻĻā§āĻāϤ⧠āĻāĻŦāĻ āĻĒāĻĄāĻŧāϤ⧠āϏāĻžāĻšāĻžāϝā§āϝ āĻāϰā§āĨ¤
// async/await āĻĻāĻŋāϝāĻŧā§
async function processOrder(userId) {
try {
const user = await getUser(userId);
const orders = await getOrders(user.id);
const details = await getOrderDetails(orders[0].id);
const result = await sendEmail(details);
return result;
} catch (err) {
console.error("Error:", err);
}
}
async keyword āĻĻāĻŋāϝāĻŧā§ function declare āĻāϰāϤ⧠āĻšāϝāĻŧ, āĻāĻŦāĻ await keyword āĻĻāĻŋāϝāĻŧā§ Promise resolve āĻšāĻāϝāĻŧāĻž āĻĒāϰā§āϝāύā§āϤ āĻ
āĻĒā§āĻā§āώāĻž āĻāϰāĻž āĻšāϝāĻŧāĨ¤ try/catch block āĻĻāĻŋāϝāĻŧā§ error handle āĻāϰāĻž āĻšāϝāĻŧāĨ¤
âī¸ What is the error-first callback convention and why is it used?â
Error-First Callback (āĻŦāĻž Node.js Callback Convention) āĻšāϞ⧠āĻāĻāĻāĻŋ standard pattern āϝā§āĻāĻžāύ⧠callback function-āĻāϰ āĻĒā§āϰāĻĨāĻŽ parameter āϏāĻŦāϏāĻŽāϝāĻŧ error āĻāĻŦāĻ āĻĻā§āĻŦāĻŋāϤā§āϝāĻŧ parameter āĻšāϞ⧠successful resultāĨ¤
// Error-first callback convention
fs.readFile("file.txt", "utf8", function (err, data) {
if (err) {
// āĻĒā§āϰāĻĨāĻŽā§ āϏāĻŦāϏāĻŽāϝāĻŧ error check āĻāϰāϤ⧠āĻšāĻŦā§
console.error("File āĻĒāĻĄāĻŧāϤ⧠āϏāĻŽāϏā§āϝāĻž āĻšāϝāĻŧā§āĻā§:", err);
return;
}
// error āύāĻž āĻĨāĻžāĻāϞ⧠data āύāĻŋāϝāĻŧā§ āĻāĻžāĻ āĻāϰā§
console.log(data);
});
āĻā§āύ āĻāĻ convention āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰāĻž āĻšāϝāĻŧ:
- Consistency: Node.js-āĻāϰ āϏāĻŦ built-in modules (āϝā§āĻŽāύ
fs,http,crypto) āĻāĻ pattern follow āĻāϰā§, āĻĢāϞ⧠developer-āϰāĻž āϏāĻšāĻā§āĻ āϝā§āĻā§āύ⧠library-āϰ āϏāĻžāĻĨā§ āĻāĻžāĻ āĻāϰāϤ⧠āĻĒāĻžāϰā§āύāĨ¤ - Explicit Error Handling: Error āϏāĻŦāϏāĻŽāϝāĻŧ āĻĒā§āϰāĻĨāĻŽā§ āĻāϏ⧠āĻŦāϞ⧠developer-āϰāĻž āĻāĻāĻžāĻā§ ignore āĻāϰāϤ⧠āĻĒāĻžāϰā§āύ āύāĻž â error check āĻāϰāĻžāĻāĻž mandatory āĻšāϝāĻŧā§ āϝāĻžāϝāĻŧāĨ¤
- Predictability: āϏāĻŦ asynchronous function āĻāĻāĻ āϧāϰāύā§āϰ signature follow āĻāϰāĻžāϝāĻŧ code predictable āĻāĻŦāĻ maintainable āĻĨāĻžāĻā§āĨ¤