Skip to main content

Menu

System onlineAI Tutorials / 2026

AI Tutorials
Knowledge search

Recent · Popular · Tutorials

  • dart3 tutorials
  • java1 tutorial
  • Javascript3 tutorials
  • Node.js Introduction2 tutorials
  • dartdart · General · In depth
  • JavascriptJavascript · Advanced · In depth
  • JavascriptJavascript · Advanced · Mid
  • JavascriptJavascript · Advanced · Short

Find a tutorial

Tell the assistant what you want to learn. It suggests published chapters.

For example: “I want to learn Rust ownership from the start.” The conversation is kept only in this tab.

0 / 2,000 characters

Enter to send, Shift+Enter for a new line. Do not include personal information.

Chapter 15

Promises

Prerequisites assumed: function scope, arrow functions, the callback pattern from "Asynchrony with Callbacks," and a working mental model of the event loop's task queue.
Level: AdvancedLength: Mid2 min read

Read at another depth

Promises

Prerequisites assumed: function scope, arrow functions, the callback pattern from "Asynchrony with Callbacks," and a working mental model of the event loop's task queue.

The core model

A Promise is a placeholder object for a value that will arrive later. It is a state machine with exactly three states: pending, fulfilled (with a value), or rejected (with a reason, usually an Error). Transitions are one-way and happen at most once. Multiple .then handlers attached to the same promise all observe the same outcome; there is no "reuse" problem like the ad-hoc callbacks of Node-style APIs.

The key insight: .then does not wait—it schedules. Every handler runs as a microtask after the current synchronous execution completes, and each .then returns a new promise, forming a chain:

Code example in javascript
function wait(ms) {
  return new Promise((resolve) => setTimeout(resolve, ms));
}

wait(500)
  .then(() => { throw new Error("boom"); })
  .catch((err) => console.error("caught:", err.message))
  .then(() => console.log("runs after recovery"));

Rejection propagates down the chain until a .catch handles it; a fulfilled value propagates until a .then transforms it.

Gotchas and trade-offs

  • Mixing construction and callbacks. Calling resolve inside a legacy callback style is fine, but forgetting reject on the error path yields a promise that hangs forever. Never construct a promise whose executor can throw after resolution—extra resolve/reject calls are silently ignored, which masks bugs.
  • Swallowed rejections. A .then without a rejection handler creates a new promise that rejects; failing to attach a .catch anywhere in the chain surfaces only as an unhandled rejection warning. Node may crash on these in future versions.
  • Non-promise values in chains. Promise.resolve(v).then(f) still defers f to a microtask; f(v) directly does not. This ordering difference matters when interleaving with I/O.
  • Combinators. Promise.all fails fast on the first rejection; Promise.allSettled never rejects; Promise.any resolves with the first fulfillment; Promise.race settles with whichever settles first. Choose by failure semantics, not convenience.
Code example in javascript
const results = await Promise.allSettled([fetch("/a"), fetch("/b")]);
const failed = results.filter((r) => r.status === "rejected");

When promises are the wrong tool

Streams, backpressure, and cancellation exceed what a single-shot promise expresses. AbortController bolted on top works, but if you need multi-value or cancellable semantics, prefer async iterables over contorted promise chains.

Exercise

Why does a .then handler attached to an already-fulfilled promise still run asynchronously rather than immediately?

Show answer

Because handlers are always queued as microtasks when their promise settles, guaranteeing uniform, predictable ordering regardless of when the promise resolved—never synchronously reentrant.

Exercise

You need every result, including failures. Which combinator and why?

Show answer

Promise.allSettled—it never rejects and reports each input as fulfilled or rejected, unlike Promise.all, which discards remaining work on the first failure.

Spotted a mistake, or code that does not work?

Report an issue

Chapter: Promises

0 / 2,000 characters

Plain text, for example: the second code sample does not compile. Do not include personal information.

You can't do that