{"post":{"slug":"what-is-a-promise-chain-2026","title":"What Is a Promise Chain in 2026? Chaining .then Explained","excerpt":"A promise chain links multiple then calls so each step waits for the last one to finish. Here is how chaining actually works, where it breaks, and how it compares to async await in 2026.","category":"code","date":"July 20, 2026","author":"ByteLedger Team","content":"<span class=\"dropcap\">A</span> promise chain is what you get when you attach one `.then()` call after another, so each step only runs once the step before it has finished. The mechanism underneath is more specific than \"run these in order\": each `.then()` returns a brand new promise, and that new promise is what the next `.then()` actually attaches to. That one fact explains why chains do not nest, and why one `catch` at the bottom can clean up after every step above it.\n\n## What changed in 2026\n\n- **Promise.withResolvers is now common in library code.** It hands you the resolve and reject functions outside the executor, replacing the manual deferred-promise pattern chains used to build by hand. Confirm runtime support before relying on it in older environments.\n- **Linters flag nested then blocks by default.** Most popular ESLint configs now warn when a then callback contains another then call, pushing teams toward flat chains or async await.\n- **AI coding assistants routinely flatten callback pyramids into chains or async await.** The rewrite that used to take an afternoon is now a quick pass, but check the rewritten error handling by hand.\n- **Top-level await in modules changed how chains get introduced.** You can start an awaited sequence at the top of a module without an async function wrapper, so new example code often skips explicit chains entirely.\n\n## How a then chain actually works\n\nEvery `.then()` call returns a new promise. If the callback returns a plain value, that new promise resolves with it immediately. If the callback returns another promise, the chain does not hand the next step a promise wrapped in a promise — it waits for the inner promise to settle first, then passes along the unwrapped result. That flattening is the entire trick behind chaining: async step follows async step while the chain still reads as one flat sequence.\n\n```javascript\ngetUser(id)\n  .then((user) => getOrders(user.id))\n  .then((orders) => orders.reduce((sum, o) => sum + o.total, 0))\n  .then((total) => console.log(\"Order total:\", total))\n  .catch((error) => console.error(\"Chain failed:\", error));\n```\n\n`getOrders` returns a promise, but the next `.then()` receives the resolved array, not a promise. Each step waits its turn automatically.\n\n## Where chains break\n\n- **Forgetting to return inside a then.** If a callback returns nothing, the next step receives `undefined` and fails somewhere downstream, often far from the real mistake.\n- **Placing a catch too early.** A catch partway through a chain only handles errors from the steps above it — anything after it is unprotected unless you add another.\n- **Branching instead of chaining.** Attaching two separate then calls to the same promise runs both independently once it settles, a common source of a step firing twice.\n- **Mixing a synchronous throw with no catch downstream.** A throw inside a then callback becomes a rejection, just like an explicit reject — easy to forget since it looks like a plain error.\n\n## Chain patterns compared\n\n| Pattern | Readability | Error handling | Best for |\n| --- | --- | --- | --- |\n| Flat .then chain | Good for short sequences | Single catch at the end | Simple linear pipelines |\n| Nested then calls | Poor, recreates the callback pyramid | Scattered, easy to miss a case | Rarely the right choice |\n| async / await | Reads top to bottom | try/catch, familiar to most developers | Most sequential logic |\n| Promise.all (parallel) | Good, explicit intent | One rejection fails the whole group | Independent steps that do not depend on each other |\n\n## Chaining versus async await\n\n`async`/`await` is not a replacement mechanism, it is different syntax over the same promise chain. The order example above is identical in behavior written this way:\n\n```javascript\nasync function printOrderTotal(id) {\n  try {\n    const user = await getUser(id);\n    const orders = await getOrders(user.id);\n    const total = orders.reduce((sum, o) => sum + o.total, 0);\n    console.log(\"Order total:\", total);\n  } catch (error) {\n    console.error(\"Chain failed:\", error);\n  }\n}\n```\n\nBoth versions build the same sequence of promises; `await` just reads more like ordinary sequential code, which is why most teams default to it in 2026. Dynamic `import()`, the mechanism behind [code splitting](/blog/what-is-code-splitting-2026), also returns a promise, so the same return-value and error-handling rules apply either way. Explicit chains still earn their place for piping a value through several transforms, attaching a `finally` that must run either way, or working inside code that mixes in callback-era APIs like the message events from a [web worker](/blog/what-is-a-web-worker-2026).\n\n## FAQ\n\n**Does every then in a chain need its own catch?**\nNo. A single catch at the end of the chain handles a rejection from any step above it, because a rejection skips the remaining then callbacks and falls through to the nearest catch.\n\n**Why does logging a then call give me a promise instead of the real value?**\nBecause `.then()` itself always returns a new promise, not the resolved value. Read or log the value inside the callback, or await the chain and log the awaited result.\n\n**Is a promise chain slower than async await?**\nNo. They compile down to the same underlying mechanism; the difference is only how the code reads, not how fast it runs.\n\n## Where to go next\n\n- [What is code splitting in 2026](/blog/what-is-code-splitting-2026)\n- [What is lazy loading in 2026](/blog/what-is-lazy-loading-2026)\n- [What is a web worker in 2026](/blog/what-is-a-web-worker-2026)","hue":320,"metaTitle":"Promise Chain in JavaScript 2026: How .then Works","metaDescription":"A 2026 guide to promise chains in JavaScript: how then returns a new promise, where chains break, error handling, and chaining versus async await.","keywords":["promise chain 2026","javascript promise chaining","then catch chain","promise chain error handling","chaining promises example","promise chain vs async await","return promise from then","sequential promises javascript","promise chain best practices"],"tldr":["**A promise chain is a sequence of then calls** — each one waits for the promise returned by the last step before it runs.","**What you return from then decides the next value** — return a plain value or a new promise and the chain unwraps it automatically.","**One catch at the end can handle errors from every step above it** — you rarely need a catch after each individual then.","**Chaining and async await use the same mechanism underneath** — await is chain syntax written to read top to bottom.","**Skip:** nesting a then call inside the callback of the one before it — each step belongs on the same chain, not indented inside the last one."],"readTime":"4 min read","wordCount":896},"related":[{"slug":"what-is-a-promise-in-javascript-2026","title":"What is a Promise in JavaScript in 2026? Async results explained","excerpt":"A Promise is a JavaScript object that represents a value that is not ready yet, like a network response. This guide explains promise states, then and catch, and how async await fits in.","category":"code","date":"May 25, 2026","author":"ByteLedger Team","readTime":"3 min read","hue":240},{"slug":"promises-explained-2026","title":"Promises explained in 2026: states, chaining, and error handling","excerpt":"Promises replaced callback hell and underpin every async JavaScript API. Here is how they work, how to chain them correctly, and where they still trip people up.","category":"code","date":"March 19, 2026","author":"ByteLedger Team","readTime":"5 min read","hue":318},{"slug":"callbacks-vs-promises-vs-async-await-2026","title":"Callbacks vs promises vs async await in 2026: which to use","excerpt":"Callbacks, promises, and async await all solve the same problem: code that has to wait. Here is the same task written three ways, and when to pick each.","category":"code","date":"July 10, 2026","author":"ByteLedger Team","readTime":"4 min read","hue":280}],"sameCategory":[{"slug":"bazel-build-explained-2026","title":"Bazel Explained: What Hermetic Builds Actually Cost","excerpt":"Bazel delivers reproducible, precisely cached builds and demands that you describe everything. Here is what you get, what it costs, and who should say no.","category":"code","date":"August 19, 2026","author":"ByteLedger Team","readTime":"3 min read","hue":145},{"slug":"graphql-federation-2026","title":"GraphQL Federation: One Graph, Many Teams","excerpt":"Federation composes independently-owned subgraphs into a single API. Here is what it solves, the operational cost it adds, and when a simpler gateway is enough.","category":"code","date":"August 19, 2026","author":"ByteLedger Team","readTime":"3 min read","hue":300},{"slug":"hermetic-builds-explained-2026","title":"Hermetic Builds Explained: Same Inputs, Same Output","excerpt":"A hermetic build depends only on declared inputs. Here is what that property gives you, the common leaks that break it, and how to move toward it incrementally.","category":"code","date":"August 19, 2026","author":"ByteLedger Team","readTime":"3 min read","hue":130},{"slug":"monorepo-tooling-compared-2026","title":"Monorepo Tooling Compared: What You Actually Need","excerpt":"Monorepo tools solve task orchestration and caching, not repository layout. Here is what each tier provides and how to tell when you have outgrown the simple option.","category":"code","date":"August 19, 2026","author":"ByteLedger Team","readTime":"3 min read","hue":150}],"newer":{"slug":"what-is-a-progressive-web-app-2026","title":"What Is a Progressive Web App in 2026? PWA Basics","excerpt":"A progressive web app is a website that can be installed, work offline, and send push notifications using standard web technology. Here is what actually makes one work in 2026.","category":"code","date":"July 20, 2026","author":"ByteLedger Team","readTime":"4 min read","hue":260},"older":{"slug":"what-is-a-proxy-vote-2026","title":"What Is a Proxy Vote? A 2026 Shareholder Guide","excerpt":"A plain-language guide to proxy voting in 2026 — how shareholders vote on company matters without attending the annual meeting, and why most proxy votes go uncast.","category":"finance","date":"July 20, 2026","author":"ByteLedger Team","readTime":"3 min read","hue":45}}