← CodeClarityLab Home
Browse by Category
+ added · updated 7d
← Back to glossary

Promises & Promise Chaining

javascript ES2015 Intermediate
debt(d5/e3/b5/t7)
d5 Detectability Operational debt — how invisible misuse is to your safety net

Closest to 'specialist tool catches it' (d5). ESLint and TypeScript can detect missing .catch() handlers and unhandled rejections in static analysis, but only when explicitly configured with strict rules. The anti-pattern of not returning inner Promises in .then() chains requires code review or runtime testing to catch reliably.

e3 Effort Remediation debt — work required to fix once spotted

Closest to 'simple parameterised fix' (e3). The quick_fix is straightforward: add .catch() to the chain or wrap in async/await with try/catch. This is typically a localized change within a single function or component, not requiring cross-file refactoring.

b5 Burden Structural debt — long-term weight of choosing wrong

Closest to 'persistent productivity tax' (b5). Promise chaining and error handling patterns shape how async code is written throughout a codebase. The choice between callback, Promise chains, async/await, and error handling strategy (catch vs try/catch) creates ongoing cognitive load and inconsistency across multiple work streams, though it doesn't redefine the entire system architecture.

t7 Trap Cognitive debt — how counter-intuitive correct behaviour is

Closest to 'serious trap' (t7). The misconception about Promise.all() failing fast versus Promise.allSettled() waiting for all operations directly contradicts what a developer might expect from similar functions in other languages. Additionally, the Promise constructor anti-pattern (wrapping already-resolved promises) feels intuitive but is inefficient and misunderstands Promise semantics—a trap that contradicts patterns in callback or async/await approaches.

About DEBT scoring →

Also Known As

JavaScript Promises Promise chain Promise.all

TL;DR

A Promise represents an asynchronous operation's eventual result — .then()/.catch()/.finally() chain handlers without nesting callbacks.

Explanation

A Promise is an object with three states: pending, fulfilled (resolved with a value), or rejected (failed with a reason). .then(onFulfilled, onRejected) returns a new Promise, enabling chains: fetch(url).then(r => r.json()).then(data => process(data)).catch(err => handle(err)). Key behaviours: returning a value from .then() wraps it in a resolved Promise; throwing propagates as rejection; returning another Promise flattens the chain. Static helpers: Promise.all() (all or fail), Promise.allSettled() (all regardless of outcome), Promise.race() (first to settle wins), Promise.any() (first to succeed). Promises replaced callback hell and underpin async/await syntax.

Diagram

flowchart LR
    PEND[Pending] -->|resolve| FULFIL[Fulfilled<br/>.then runs]
    PEND -->|reject| REJECT[Rejected<br/>.catch runs]
    FULFIL --> CHAIN[Chain<br/>.then returns new Promise]
    subgraph async/await sugar
        ASYNC[async function] -->|awaits| PROM[Promise]
        PROM -->|resolved| RESUME[resumes after await]
        PROM -->|rejected| THROW[throws - use try/catch]
    end
style FULFIL fill:#238636,color:#fff
style REJECT fill:#f85149,color:#fff
style PEND fill:#d29922,color:#fff

Common Misconception

Promise.all fails immediately if any one promise rejects. Promise.all does fail fast on the first rejection, but Promise.allSettled waits for all promises regardless of outcome — use allSettled when you need results from all operations even if some fail.

Why It Matters

Promises represent eventual asynchronous values — chaining .then() and .catch() replaces callback hell with composable, readable async flows that can be combined with Promise.all and Promise.race.

Common Mistakes

  • Missing .catch() on a Promise chain — unhandled rejections crash Node.js and are silently swallowed in browsers.
  • Creating a new Promise wrapping another Promise unnecessarily — the Promise constructor anti-pattern.
  • Not returning the inner Promise in a .then() callback — the chain breaks and errors escape.
  • Using Promise.all() when one failure should not cancel the others — use Promise.allSettled() instead.

Code Examples

✗ Vulnerable
// Promise chain with missing return — error escapes:
fetchUser(id)
    .then(user => {
        fetchOrders(user.id); // Missing return! Chain doesn't wait for this
    })
    .then(orders => console.log(orders)) // orders is undefined
    .catch(err => console.error(err));   // Errors from fetchOrders not caught
✓ Fixed
// Promise.all — parallel, fails if any rejects
const [user, orders, prefs] = await Promise.all([
  fetchUser(id),
  fetchOrders(id),
  fetchPreferences(id),
]);

// Promise.allSettled — parallel, never throws, check each result
const results = await Promise.allSettled([fetchA(), fetchB()]);
results.forEach(r => {
  if (r.status === 'fulfilled') console.log(r.value);
  else console.error(r.reason);
});

// Promise.race — first to settle wins (timeout pattern)
const withTimeout = (promise, ms) => Promise.race([
  promise,
  new Promise((_, reject) => setTimeout(() => reject(new Error('Timeout')), ms)),
]);

// Promise.any — first to SUCCEED wins (ignores rejections)
const fastest = await Promise.any([mirror1(), mirror2(), mirror3()]);

Added 15 Mar 2026
Edited 22 Mar 2026
Views 35
Rate this term
No ratings yet
🤖 AI Guestbook educational data only
| |
Last 30 days
0 pings F 0 pings S 0 pings S 0 pings M 0 pings T 0 pings W 0 pings T 0 pings F 0 pings S 0 pings S 0 pings M 0 pings T 0 pings W 1 ping T 0 pings F 1 ping S 2 pings S 0 pings M 1 ping T 0 pings W 1 ping T 1 ping F 2 pings S 0 pings S 0 pings M 0 pings T 0 pings W 1 ping T 0 pings F 0 pings S
No pings yet today
No pings yesterday
Perplexity 9 Amazonbot 6 Google 3 SEMrush 3 ChatGPT 3 Unknown AI 2 Ahrefs 2 Majestic 1 Qwen 1
crawler 28 crawler_json 2
DEV INTEL Tools & Severity
🟡 Medium ⚙ Fix effort: Low
⚡ Quick Fix
Chain .catch() on every promise or use async/await with try/catch — unhandled rejections crash Node.js and silence errors in browsers
📦 Applies To
javascript ES2015 web cli
🔗 Prerequisites
🔍 Detection Hints
Promise without .catch() or try/catch; new Promise executor with synchronous throw not caught
Auto-detectable: ✓ Yes eslint typescript
⚠ Related Problems
🤖 AI Agent
Confidence: Medium False Positives: Medium ✗ Manual fix Fix: Medium Context: Function Tests: Update

✓ schema.org compliant