Promise.then(): Each Call Returns a New Promise

Each .then() call returns a new promise, letting you chain async tasks sequentially. This is key for multi-step operations like API calls. The footgun is attaching multiple .then()s to the original promise, which executes them in parallel, not in sequence.
Why it exists
Before promises, chaining asynchronous operations required deeply nested callbacks, a pattern nicknamed "callback hell" or the "pyramid of doom." This code was hard to read, debug, and maintain. Promise chaining with .then() was created to flatten this structure, allowing developers to write asynchronous code that reads more like a sequential, synchronous script.
The mental model
A promise chain is like an assembly line. Each .then() is a station. It receives the resolved value from the previous station, performs its task, and passes its result to the next station in the line. The crucial insight is that every .then() call creates and returns a new promise (a new station), which is how the chain is built. If you attach two .then() handlers to the same original promise, you're adding two workers to the first station; they will both start at the same time once the initial work is done, not one after the other.
How it works
The .then() method immediately returns a new, pending promise. When the promise it was called on settles (fulfills or rejects), its corresponding handler function is executed asynchronously. The outcome of this new promise is determined by what the handler does. If the handler returns a value, the new promise fulfills with that value. If it throws an error, the new promise rejects with that error. If it returns another promise, the new promise will adopt the state and value of that returned promise. This allows values and errors to propagate cleanly down the chain.
When to use it
Use promise chaining for any sequence of asynchronous tasks where each step depends on the result of the previous one. This is common for API calls (fetch user, then fetch their posts), database transactions (insert a user, then use their new ID to insert a record in another table), or file system operations (read a config file, then connect to the server it specifies).
When not to use it
Do not use chaining for independent asynchronous tasks that can be run concurrently. For that, Promise.all() is the correct tool. It takes an array of promises and resolves only when all of them are complete, which is far more efficient than waiting for each one to finish in sequence. Also, avoid manually creating new Promise inside a .then if you can simply return a value or another promise.
One canonical example
A classic example is fetching user data, then using that data to fetch their posts. You would call fetch for the user URL, use a .then to parse the response as JSON. The next .then in the chain receives the user object, from which you can construct the posts URL and return a new fetch call. Subsequent .then calls handle the response from the posts API. A single .catch at the end of the chain can handle an error from any preceding step.
Interview question
What is the fundamental mechanism by which Promise.then() enables sequential asynchronous operations?
- a.Each call to .then() returns a new promise, whose resolution depends on the preceding handler's outcome.Correct
- b.It attaches multiple handlers to the original promise, which then execute in a defined order.
- c.It directly executes the next handler function only after the previous one finishes.
- d.It gathers all promises in a chain and resolves them concurrently once all are ready.
Why? this is the answer
The core mechanism for chaining is that every .then() call creates and returns a new promise, allowing the next step in the sequence to wait for the previous one's resolution. Option C describes the outcome but not the underlying mechanism of how this sequential execution is achieved. Option B describes a common misconception where multiple handlers attached to the *same* promise execute in parallel, not sequentially.
Just read this? Test yourself on what you have been reading.
Read the original → developer.mozilla.org
You just looked this up. Could you explain it out loud?
That is the part interviews actually test. Tezvyn takes questions like this one and gives you what the interviewer is really checking, the answer that lands, and the mistake that ends the conversation, in the four minutes before your next meeting.
The iPhone app is on the way
We are building it. Until it lands, nothing here is held back from you: every interview card, your saved cards, streaks and the job board all work in Safari, plus hundreds of free practice quizzes of thirty questions each. Sign in and it all carries over to the app the day it arrives.
Want it as an icon? Tap Share at the bottom of Safari, then Add to Home Screen. It opens full screen and the cards you have read stay available offline.
We are hiring for this. Open roles that interview on javascript — each one lists the topics its interview covers.
See open roles