What are Promises in JavaScript?
Learn JavaScript Promises: pending, fulfilled, and rejected states, chaining with then/catch, and Promise.all with clear examples and interview answers.
Expected Interview Answer
A Promise is an object representing the eventual result of an asynchronous operation, existing in one of three states: pending, fulfilled, or rejected.
Promises give async code a clean, chainable structure that replaces deeply nested callbacks. You attach .then() to handle a fulfilled value, .catch() to handle errors, and .finally() for cleanup. Once a Promise settles (fulfilled or rejected) its state and value are locked and cannot change. Because .then() returns a new Promise, calls can be chained sequentially, and helpers like Promise.all, Promise.race, and Promise.allSettled coordinate multiple Promises at once.
- Avoids deeply nested callback hell
- Standardised, chainable error handling with .catch()
- Immutable state once settled
- Composes multiple async tasks with Promise.all/race
- Foundation for async/await syntax
AI Mentor Explanation
A Promise is like a third-umpire review request: the moment you send it up, you get a ticket that guarantees an eventual answer. Right now it is pending; soon it settles as out (fulfilled) or not out (rejected). You don't stand frozen waiting — you register what to do for each verdict, and once the big screen shows the decision it is final and cannot be changed.
Step-by-Step Explanation
Step 1
Create the Promise
new Promise((resolve, reject) => { ... }) runs an executor that starts the async work immediately.
Step 2
Start in pending
Until you call resolve or reject, the Promise sits in the pending state.
Step 3
Settle once
Calling resolve(value) fulfills it; calling reject(error) rejects it. The first call wins and locks the state.
Step 4
Attach handlers
Use .then(onFulfilled) for the value and .catch(onError) for failures; .finally() runs regardless.
Step 5
Chain sequentially
Each .then() returns a new Promise, so returning a value or Promise inside it feeds the next .then().
Step 6
Combine many
Promise.all waits for all to fulfill, Promise.race settles on the first, Promise.allSettled reports every outcome.
What Interviewer Expects
- The three states: pending, fulfilled, rejected
- How .then, .catch, and .finally are used
- That a settled Promise is immutable
- Chaining because .then returns a new Promise
- Knowledge of Promise.all vs race vs allSettled
Common Mistakes
- Forgetting to return inside .then, breaking the chain
- Not adding .catch, so rejections become unhandled
- Thinking a Promise can change state after settling
- Confusing Promise.all (all succeed) with Promise.race (first settles)
- Believing the executor function runs asynchronously later
Best Answer (HR Friendly)
“A Promise is JavaScript's way of representing a result that isn't ready yet, like a receipt for an online order. You say what to do when it succeeds and what to do if it fails, and the code carries on smoothly instead of getting stuck waiting.”
Code Example
function fetchUser(id) {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (id > 0) resolve({ id, name: 'Ada' })
else reject(new Error('Invalid id'))
}, 500)
})
}
fetchUser(1)
.then((user) => {
console.log('Got user:', user.name)
return user.id
})
.then((id) => console.log('User id is', id))
.catch((err) => console.error('Failed:', err.message))
.finally(() => console.log('Done'))const p1 = Promise.resolve('a')
const p2 = new Promise((res) => setTimeout(() => res('b'), 100))
Promise.all([p1, p2]).then((values) => {
console.log(values) // ['a', 'b'] once both fulfill
})
Promise.race([p1, p2]).then((first) => {
console.log(first) // 'a' — the first to settle
})Follow-up Questions
- What is the difference between Promise.all and Promise.allSettled?
- How does async/await relate to Promises?
- What happens to an unhandled Promise rejection?
- Can you cancel a Promise once it is pending?
- Why does .then always return a new Promise?
MCQ Practice
1. How many times can a Promise change its state?
A Promise settles exactly once; the first resolve or reject locks its state and value, and later calls are ignored.
2. What does Promise.all do if one of its Promises rejects?
Promise.all rejects as soon as any input Promise rejects. Use Promise.allSettled if you need every outcome regardless of failures.
3. What does a .then() callback return that enables chaining?
.then() returns a new Promise that resolves with whatever the callback returns, which is what makes sequential chaining possible.
Flash Cards
What are the three Promise states? — Pending (not settled), fulfilled (resolved with a value), and rejected (settled with an error).
What does .finally() do? — Runs a callback after the Promise settles, regardless of whether it was fulfilled or rejected — ideal for cleanup.
Promise.all vs Promise.race? — all fulfills when every Promise fulfills (rejects on the first rejection); race settles as soon as the first Promise settles.
Is a settled Promise mutable? — No. Once fulfilled or rejected, its state and value are fixed and cannot change.