Asynchronous code is at the heart of JavaScript. Understanding it unlocks the full power of the language.
The problem: callbacks
The old way to handle async work was callbacks:
javascriptfetchUser(id, function(err, user) {
if (err) return handleError(err);
fetchPosts(user.id, function(err, posts) {
if (err) return handleError(err);
render(posts);
});
});
This leads to “callback hell” — deeply nested, hard-to-read code.
Promises to the rescue
A Promise represents a value that may be available now, in the future, or never:
javascriptfetchUser(id)
.then(user => fetchPosts(user.id))
.then(posts => render(posts))
.catch(err => handleError(err));
Much cleaner! The .then() chain reads left-to-right.
Creating your own Promise
javascriptfunction delay(ms) {
return new Promise(resolve => {
setTimeout(resolve, ms);
});
}
delay(1000).then(() => console.log('1 second passed'));
async/await: synchronous-looking async code
async/await is syntax sugar over Promises:
javascriptasync function loadDashboard(userId) {
try {
const user = await fetchUser(userId);
const posts = await fetchPosts(user.id);
render(posts);
} catch (err) {
handleError(err);
}
}
An async function always returns a Promise. Inside it, await pauses execution until the Promise resolves.
Running tasks in parallel
Use Promise.all when tasks are independent:
javascriptasync function loadAll(userId) {
const [user, settings] = await Promise.all([
fetchUser(userId),
fetchSettings(userId)
]);
return { user, settings };
}
Promise.all rejects as soon as any Promise rejects. Use Promise.allSettled to wait for all, regardless of outcome.
Error handling patterns
javascript// Option 1: try/catch
async function safe() {
try {
return await riskyOperation();
} catch (err) {
console.error('Failed:', err);
return null;
}
}
// Option 2: catch on the awaited promise
const result = await riskyOperation().catch(() => null);
Summary
| API | When to use |
|---|---|
Promise |
Wrapping async APIs, composing chains |
.then().catch() |
Functional style, libraries |
async/await |
Application code, readability |
Promise.all |
Independent parallel tasks |
Promise.allSettled |
When you need all results regardless of failure |