Promise chaining in JavaScript is the practice of connecting async steps so the result of one step flows into the next. It is a core pattern for working with fetch calls, data transforms, and other promise-based operations.
The usual tools are .then(), .catch(), async/await, and Promise.all(). If you need to wait for a single async task first, wait for async function to finish is the related pattern.
Tested on: Node.js v20.18.2. A short note after each runnable snippet describes what you should see in the console.
Method 1: Chain promises with then()
.then() passes a resolved value to the next step in the chain.
Promise.resolve("step-1")
.then((value) => {
console.log("promise-chain:", value);
return "step-2";
})
.then((value) => console.log("promise-chain:", value));You should see 2 lines, in order: promise-chain: step-1, promise-chain: step-2.
This is the foundation of promise chaining and is still common in readable async pipelines.
Method 2: Handle failures with catch()
.catch() catches a rejected promise anywhere earlier in the chain.
Promise.reject(new Error("failed"))
.then(() => console.log("no-op"))
.catch((error) => console.log("promise-catch:", error.message));You should see one line logging promise-catch: failed.
Use this when you want one error handler for the whole promise sequence.
Method 3: Chain promises with async and await
await lets you write the next promise step in a direct sequence.
async function run() {
const value = await Promise.resolve("async-step");
console.log("promise-async:", value);
}
run();You should see one line logging promise-async: async-step.
This is the preferred style when you want promise chaining with clearer control flow.
Summary
Promise chaining in JavaScript connects async operations with then(), catch(), and async/await. Use it when one promise depends on another, and use Promise.all() when multiple promises can run in parallel.
