Asynchronous JavaScript
Callbacks, Promises, and async/await patterns
Async Patterns
JavaScript is single-threaded. Asynchronous code lets it handle I/O without blocking. The evolution: callbacks → Promises → async/await.
js
// Async Evolution
// 1. Callbacks — leads to "callback hell"
fs.readFile("a.txt", (err, dataA) => {
fs.readFile("b.txt", (err, dataB) => {
fs.readFile("c.txt", (err, dataC) => {
// deeply nested = hard to read
});
});
});
// 2. Promises — chainable, .then/.catch
function fetchUser(id) {
return fetch(`/api/users/${id}`)
.then(res => {
if (!res.ok) throw new Error("Not found");
return res.json();
});
}
fetchUser(1).then(user => console.log(user)).catch(console.error);
// 3. async/await — cleanest syntax
async function getUser(id) {
try {
const res = await fetch(`/api/users/${id}`);
if (!res.ok) throw new Error("Not found");
return await res.json();
} catch (err) {
console.error("Failed:", err.message);
}
}
// Parallel execution
const [users, posts] = await Promise.all([
fetch("/api/users").then(r => r.json()),
fetch("/api/posts").then(r => r.json()),
]);
// Promise.allSettled — don't fail if one rejects
const results = await Promise.allSettled([p1, p2, p3]);
// results: [{ status: "fulfilled", value }, { status: "rejected", reason }]💬 Difference between Promise.all and Promise.allSettled?
Promise.all rejects immediately if ANY promise rejects (fail-fast). Promise.allSettled waits for ALL to complete and returns results for each (fulfilled or rejected). Use allSettled when you need all results regardless of failures.