Loading lesson path
In Node.js, asynchronous operations let your program do other work while waiting for tasks like file I/O or network requests to complete.Formula
This non - blocking approach enables Node.js to handle thousands of concurrent connections efficiently.Formula
Uses callbacks, promises, or async/awaitExample: Synchronous File Read const fs = require('fs');
console.log('1. Starting sync read...');
const data = fs.readFileSync('myfile.txt', 'utf8');
console.log('2. File contents:', data);
console.log('3. Done reading file');
Output will be in order: 1 â 2 â 3 (blocks between each step)Example: Asynchronous File Read const fs = require('fs');
console.log('1. Starting async read...');
fs.readFile('myfile.txt', 'utf8', (err, data) => {
if (err) throw err;
console.log('2. File contents:', data);
});
console.log('3. Done starting read operation');
Output order: 1 â 3 â 2 (doesn't wait for file read to complete)Problem: Nested Callbacks (Callback Hell)
getUser(userId, (err, user) => {
if (err) return handleError(err);
getOrders(user.id, (err, orders) => {
if (err) return handleError(err);
processOrders(orders, (err) => {
if (err) return handleError(err);
console.log('All done!');
});
});
});
Solution: Use Promises getUser(userId).then(user => getOrders(user.id)).then(orders => processOrders(orders)).then(() => console.log('All done!')).catch(handleError);Formula
Even Better: Async/Await async function processUser(userId) {try {
const user = await getUser(userId);
const orders = await getOrders(user.id);
await processOrders(orders);
console.log('All done!');
} catch (err) {
handleError(err);
}
}1. Promises const fs = require('fs').promises;
console.log('1. Reading file...');
fs.readFile('myfile.txt', 'utf8').then(data => {
console.log('3. File content:', data);
}).catch(err => console.error('Error:', err));
console.log('2. This runs before file is read!');Formula
2. Async/Await (Recommended)async function readFiles() {
try {
console.log('1. Starting to read files...');
const data1 = await fs.readFile('file1.txt', 'utf8');
const data2 = await fs.readFile('file2.txt', 'utf8');
console.log('2. Files read successfully!');
return { data1, data2 };
} catch (error) {
console.error('Error reading files:', error);
}
}// Use async/await for better readability async function getUserData(userId) {
try {
const user = await User.findById(userId);
const orders = await Order.find({ userId });
return { user, orders };
} catch (error) {
console.error('Failed to fetch user data:', error);
throw error; // Re-throw or handle appropriately
}
}// Nested callbacks are hard to read and maintain
User.findById(userId, (err, user) => {
if (err) return console.error(err);
Order.find({ userId }, (err, orders) => {
if (err) return console.error(err);// Process orders...
});
});Formula
â
Use async/await for better readability
â
Always handle errors with try/catchâ Run independent operations in parallel with Promise.all â Avoid mixing sync and async code patterns â Don't forget to await promises
// Run multiple async operations in parallel async function fetchAllData() {
try {
const [users, products, orders] = await Promise.all([
User.find(),
Product.find(),
Order.find()
]);
return { users, products, orders };
} catch (error) {
console.error('Error fetching data:', error);
throw error;
}
}Asynchronous code lets Node.js handle many requests at once, without waiting for slow operations like file or database access.
Formula
This makes Node.js great for servers and real - time apps.Asynchronous Programming in Node.js
Formula
Node.js uses an event loop for non - blocking I/OPromise.all for parallel operations