Reading — step 1 of 7
Learn
A Promise represents a value that will be available later — or never, if it fails. Network requests, file I/O, timers, database queries — anything asynchronous returns a Promise (or should).
Before Promises, async code looked like nested callbacks ("callback hell"). Promises let you compose async operations linearly, with proper error handling.
Creating a Promise
The constructor takes a function with two parameters: resolve and reject. Call exactly ONE of them when your async work finishes.
In practice, you rarely use new Promise directly — you USE Promises returned by APIs (fetch, fs.promises, etc).
The three states
- pending — the initial state, work not yet finished.
- fulfilled — completed with a value (
resolve(value)was called). - rejected — failed with a reason (
reject(error)was called).
Once settled (fulfilled OR rejected), a Promise's state is immutable. Calling resolve twice does nothing the second time.
.then() and chaining
.then(onFulfilled, onRejected) registers callbacks for when the Promise settles. The KEY insight: each .then() returns a NEW Promise. That's how you build pipelines.
If any step in the chain throws or returns a rejected Promise, control jumps to the nearest .catch(). ONE catch handles errors from the entire chain.
Returning from .then()
What you return from a .then callback determines what the next .then sees:
- Return a plain value → next
.thengets that value. - Return a Promise → JavaScript waits for it; next
.thengets its resolved value. - Throw → chain rejects; next
.catchruns.
Combinators
Use Promise.all for parallel tasks where one failure should fail the whole batch. Use Promise.allSettled when you want every result regardless.
Microtasks — the hidden detail
Promise callbacks run in the microtask queue, processed after the current synchronous code but before macrotasks (setTimeout):
Microtasks > macrotasks > pending I/O. Knowing this matters for tests and ordering-sensitive code.
Common mistakes
- Forgetting to return a Promise inside
.then— chain breaks, next.thengets undefined. .catchonly at the end of one chain — won't catch errors from a SIBLING chain.- Not handling rejection — uncaught Promise rejections cause warnings (and crash in newer Node).
- Calling
resolvetwice — silent no-op the second time. State is locked after first settle.
Discussion
Ask a question, share an insight, or help someone who’s stuck.
Sign in to post a comment or reply.
Loading…