Skip to main content

How does promise chaining work?

What promise chaining is

Promise chaining is the sequential execution of asynchronous actions, where the result of one .then() is passed to the next.

Every .then(), .catch() and .finally() returns a new promise, which makes it possible to build a linear processing flow - without "callback hell".

Basic chain example

javascript
new Promise((resolve) => { setTimeout(() => resolve(10), 1000); }) .then((num) => { console.log('1. Got:', num); return num * 2; }) .then((num) => { console.log('2. Multiplied:', num); return num + 5; }) .then((result) => { console.log('3. Result:', result); });

Output:

javascript
1. Got: 10 2. Multiplied: 20 3. Result: 25

Each .then():

  1. receives the result of the previous step,
  2. returns a new promise,
  3. passes its result further down the chain.

How it works under the hood

  1. The first promise is created and moves to pending. When resolve(value) is called, it becomes fulfilled.
  2. The first .then() receives value, and returns a new promise, which now waits for the next result.
  3. Every .then() in the chain waits for the previous one to finish, even if a new promise is returned inside it.

Example with an async step

javascript
Promise.resolve(1) .then((n) => { console.log('A:', n); return new Promise((resolve) => setTimeout(() => resolve(n + 1), 1000) ); }) .then((n) => { console.log('B:', n); return n * 3; }) .then((n) => console.log('C:', n));

Output (after one second):

javascript
A: 1 B: 2 C: 6

Here:

  • .then() "recognizes" that a new promise was returned to it,
  • waits for it to finish (resolve),
  • and only then runs the next step of the chain.

Errors in the chain

If an error occurs in any .then() (throw or reject), all following .then() calls are skipped, and control passes to the nearest .catch().

javascript
Promise.resolve(10) .then((x) => x / 2) .then(() => { throw new Error('Error!'); }) .then(() => console.log('will not run')) .catch((err) => console.error('Caught:', err.message)) .then(() => console.log('continuing'));

Output:

javascript
Caught: Error! continuing

Returning values and promises from .then()

What .then() returnsWhat happens
A plain valueIt gets wrapped in Promise.resolve(value)
A promiseThe chain waits for it to finish
An error (throw)The chain moves to rejected
Nothingundefined is passed further

Combination example

javascript
Promise.resolve('A') .then((v) => v + 'B') // returns 'AB' .then((v) => Promise.resolve(v + 'C')) // waits for another promise .then((v) => v + 'D') .then(console.log); // ABDC

.catch() can be used in the middle of a chain

javascript
Promise.reject('Error') .catch((err) => { console.log('Caught:', err); return 'Recovered'; }) .then((v) => console.log('Next:', v));

Output:

javascript
Caught: Error Next: Recovered

.catch() also returns a new promise, so the chain continues after the error is handled.

.finally() in a chain

finally() always runs, regardless of the result, and it does not change the value (unless it throws an error):

javascript
Promise.resolve('OK') .finally(() => console.log('Cleaning up...')) .then(console.log);

Output:

javascript
Cleaning up... OK

Example of a full chain with errors

javascript
Promise.resolve(1) .then((x) => x + 1) .then(() => { throw new Error('Oops!'); }) .catch((e) => { console.log('Error caught:', e.message); return 5; }) .then((x) => console.log('Result:', x)) .finally(() => console.log('Done'));

Output:

javascript
Error caught: Oops! Result: 5 Done

A simple analogy

Think of a promise chain as an assembly line.

  • Each .then() is a station, where the part gets processed;
  • If something goes wrong, .catch() fixes the error and puts the part back on the line;
  • At the end, .finally() turns off the machines and sweeps the floor.

Summary

FeatureDescription
Every .then()Returns a new promise
Values flow downwardThe result from .then() goes into the next one
ErrorsPropagate down to the nearest .catch()
.finally()Runs no matter what
ChainingLets you write async code linearly, without nesting

Short Answer

Interview ready
Premium

A concise answer to help you respond confidently on this topic during an interview.