Lesson 8 of 80
An object that stands in for a value you don't have yet — how JavaScript escaped callback hell, and the machinery async/await is built on.
14 min read
Every option explains itself — why the right one is right, and why each wrong one is wrong. Miss one and it comes back later on a spaced-repetition schedule.
Question 1 of 3
A promise's resolve() is called twice in a row, with different values. What happens?
Hints without spoilers, and a plain explanation of why a wrong answer was wrong — answered only from this lesson. Free account, no card.
Sign up freeWhat interviewers actually ask about this, and what a strong answer has to cover.
A strong answer covers
Likely follow-ups
A promise is a placeholder for a value that doesn't exist yet. You get the placeholder immediately; the real value (or an error) arrives later.
Every promise is in exactly one state at a time:
Once it leaves pending, it's settled — for good. A promise can't fulfill and then reject, or settle twice.
Before promises, chaining async steps meant nesting callbacks inside callbacks:
getUser(id, (user) => {
getPosts(user.id, (posts) => {
getComments(posts[0].id, (comments) => {
console.log(comments); // three levels deep, and error handling at each one
});
});
});
Promises flatten that into a chain, because .then() always returns a new promise:
getUser(id)
.then((user) => getPosts(user.id))
.then((posts) => getComments(posts[0].id))
.then((comments) => console.log(comments))
.catch((err) => console.error(err)); // one place to catch any failure in the chain
A promise starts pending — it stands in for a value that doesn't exist yet.
resolve() twice, or resolve() then reject(), does nothing the second time — the first settlement wins..then() always returns a new promise, not the same one. That's what makes chaining work, and why you must return a value inside .then() to pass it down the chain..catch() for a rejected promise, most runtimes log a loud warning — it just doesn't crash synchronously like a thrown error would.Promise.all fails fast. One rejected promise in the array rejects the whole Promise.all, even if the others would have succeeded. Promise.allSettled is the version that waits for everyone.Promises are the foundation async/await sits on — you can't reason about await without knowing what it's await-ing. Interviewers use promise-ordering questions (see the event loop lesson) specifically to check this isn't memorized syntax.