How do Promises work in JavaScript?
A Promise represents a value that is not yet available. It has three states: pending, fulfilled, or rejected. Chain .then() and .catch() to handle the result.
JavaScriptAsync
Overview
A Promise is an object that represents the eventual completion (or failure) of an async operation. It starts as `pending`, then either becomes `fulfilled` (success) or `rejected` (failure). You handle the outcome with `.then()`, `.catch()`, and `.finally()` - or with `async/await` which is syntactic sugar over Promises.
Key Points
- •Three states: `pending` → either `fulfilled` (value) or `rejected` (reason).
- •`.then(onFulfilled, onRejected)` - handle success and/or error.
- •`.catch(onRejected)` - shorthand for `.then(undefined, onRejected)`.
- •`.finally(fn)` - runs regardless of outcome; useful for cleanup.
- •Promises are chainable: each `.then()` returns a new Promise.
- •`Promise.all([...])` waits for all; `Promise.race([...])` resolves/rejects with the first to settle.
Examples
Creating and consuming a Promise
javascriptconst fetchUser = (id) =>
new Promise((resolve, reject) => {
setTimeout(() => {
if (id > 0) resolve({ id, name: 'Alice' });
else reject(new Error('Invalid ID'));
}, 500);
});
fetchUser(1)
.then(user => console.log(user.name)) // 'Alice'
.catch(err => console.error(err.message))
.finally(() => console.log('done'));Promise chaining
javascriptfetch('/api/user/1')
.then(res => {
if (!res.ok) throw new Error(`HTTP ${res.status}`);
return res.json(); // returns another Promise
})
.then(user => user.name)
.then(name => console.log('User:', name))
.catch(err => console.error('Failed:', err.message));Promise.all - run in parallel
javascriptconst [user, posts, comments] = await Promise.all([
fetch('/api/user/1').then(r => r.json()),
fetch('/api/posts').then(r => r.json()),
fetch('/api/comments').then(r => r.json()),
]);
// All three requests run simultaneouslyIf any promise rejects, Promise.all rejects immediately.
Promise.allSettled - handle partial failures
javascriptconst results = await Promise.allSettled([
fetch('/api/fast'),
fetch('/api/might-fail'),
]);
results.forEach(result => {
if (result.status === 'fulfilled') console.log(result.value);
else console.error(result.reason);
});allSettled never rejects - you get all outcomes (success or failure) for each promise.
Pro Tip
Prefer `async/await` syntax over `.then()` chains for readability - but know that they are the same underneath. `async/await` shines for sequential async steps; `Promise.all` is still the best tool for parallel async operations.