Promises in Node

The Async Primitive — Same As The Browser

Promises in Node

Promises in Node are the same as the browser. Use them to represent pending async work.

3 min read Level 1/5 #nodejs#promises#async
What you'll learn
  • Author a function that returns a promise
  • Chain with then/catch
  • Run in parallel with Promise.all

Promises in Node are identical to browser promises — same spec, same methods. Skip ahead if you already know them; here’s the Node-relevant summary.

A Promise

A value that will be available eventually:

import { readFile } from "node:fs/promises";

const p = readFile("data.txt", "utf8");
// p is a Promise — it hasn't resolved yet

p.then((text) => console.log("got", text))
 .catch((err) => console.error("failed", err));

Authoring One

For wrapping callback APIs or doing custom async:

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

await wait(1000);
console.log("after 1s");

For real code, use timers/promises:

import { setTimeout as wait } from "node:timers/promises";
await wait(1000);

The Static Combinators

MethodResolves when…
Promise.all([p1, p2])All resolve. Rejects on first rejection.
Promise.allSettled([p1, p2])All settle (resolve OR reject). Never rejects.
Promise.race([p1, p2])The first settles.
Promise.any([p1, p2])The first resolves (ignores rejections).
const [users, posts, comments] = await Promise.all([
  fetch("/users").then(r => r.json()),
  fetch("/posts").then(r => r.json()),
  fetch("/comments").then(r => r.json()),
]);

Three HTTP calls in parallel, one await. Much faster than serial.

Handling Errors

readFile("missing.txt", "utf8")
  .then((text) => console.log(text))
  .catch((err) => {
    if (err.code === "ENOENT") {
      console.warn("not there");
    } else {
      throw err;
    }
  });

In Promise.all, the first rejection rejects the whole. For “do all, collect results” semantics, use Promise.allSettled.

Up Next

async/await — promises wearing a more readable shirt.

async/await →