13 / 20 · Day 5
Day 5 · Concept 13

Promises

A Promise is a value that will exist later — either fulfilled with a value or rejected with a reason. .then chains; .catch handles errors; Promise.all parallelises.


1 · The basics

js promise.js
function delay(ms, value) {
    return new Promise(resolve => setTimeout(() => resolve(value), ms));
}

delay(50, "first")
    .then(v => {
        console.log(v);
        return delay(50, "second");
    })
    .then(v => console.log(v))
    .catch(err => console.error("oops:", err));

2 · The three states

StateMeans
pendingJust created; not done.
fulfilledResolved with a value. .then handler fires.
rejectedRejected with a reason. .catch handler fires.

Once a promise leaves pending, it can't change again. Hence "promise" — a final value, not a placeholder.

3 · Combinators — parallel and sequential

js combinators.js
function delay(ms, v) { return new Promise(r => setTimeout(() => r(v), ms)); }

// All — wait for all to fulfil; fail fast on any reject
Promise.all([delay(30, "a"), delay(50, "b"), delay(10, "c")])
    .then(values => console.log("all:", values));

// AllSettled — wait for all, never fails
Promise.allSettled([Promise.resolve("ok"), Promise.reject("err")])
    .then(results => console.log("settled:", results.map(r => r.status)));

// Race — first to settle wins
Promise.race([delay(50, "slow"), delay(10, "fast")])
    .then(v => console.log("race:", v));

// Any — first to fulfil
Promise.any([Promise.reject("x"), delay(20, "ok")])
    .then(v => console.log("any:", v));

4 · Errors propagate

js errors.js
Promise.resolve("ok")
    .then(v => {
        if (v === "ok") throw new Error("boom");
        return v;
    })
    .then(v => console.log("step 2:", v))   // skipped
    .catch(err => console.error("caught:", err.message))
    .finally(() => console.log("cleanup"));

A thrown error or returned-rejected promise skips all subsequent .thens until a .catch. .finally always runs.

5 · Common mistakes

  • Forgetting to return inside a .then. Without return, the next .then sees undefined.
  • Unhandled rejections. Always have a final .catch or it logs an "Unhandled promise rejection" warning.
  • Nesting .then instead of chaining. Flat chain reads better.
  • Calling the executor function manually. new Promise(resolve, reject) runs synchronously when constructed — anything async needs to be inside the executor.

6 · When it clicks

  • You chain .thens by reflex instead of nesting callbacks.
  • You reach for Promise.all for parallel work without thinking.
  • You're about to learn async/await — which is just sugar on promises.
Found this useful?