Handling Asynchronous Operations

1. Using Callbacks

Example: Node-style callback

import fs from "node:fs";
fs.readFile("a.txt", "utf8", (err, data) => {
  if (err) return console.error(err);
  console.log(data);
});
ConventionDetail
Error first(err, result) => ...
Single invocationDon't call twice

2. Working with Promises

Example

fetch("/api").then((r) => r.json()).then(console.log).catch(console.error);
StateMeaning
pendingInitial
fulfilledResolved with value
rejectedFailed with reason

3. Using Async/Await Syntax

Example

async function loadUser(id) {
  try {
    const res = await fetch(`/users/${id}`);
    if (!res.ok) throw new Error(res.statusText);
    return await res.json();
  } catch (err) { console.error("loadUser failed", err); throw err; }
}

4. Converting Callbacks to Promises (util.promisify)

Example

import { promisify } from "node:util";
import fs from "node:fs";
const readFile = promisify(fs.readFile);
const data = await readFile("a.txt", "utf8");
HelperUse
util.promisifyWrap (err, data) callback fns
util.callbackifyReverse direction
Native Promise APIsPrefer fs/promises, dns/promises, etc.

5. Handling Promise Rejection

PatternUse
.catch(handler)Chain
try/catch awaitAsync/await
process.on("unhandledRejection")Last resort
--unhandled-rejections=strictCrash on unhandled

6. Using Promise.all for Parallel Execution

Example

const [user, posts] = await Promise.all([fetchUser(id), fetchPosts(id)]);
BehaviorDetail
ResolvesAll settled successfully → array
RejectsFirst rejection (others keep running)

7. Using Promise.race for First Resolution

Resolves WithNotes
First settled (fulfill or reject)Useful for timeouts

8. Using Promise.allSettled for All Results

Example

const results = await Promise.allSettled(urls.map((u) => fetch(u)));
const ok = results.filter((r) => r.status === "fulfilled");

9. Using Promise.any for First Fulfillment

BehaviorDetail
ResolvesFirst fulfilled
RejectsAll rejected → AggregateError

10. Understanding Async Error Handling (try-catch)

PatternNotes
try { await x } catch (e) {}Catches both sync and async errors
Forgetting awaitErrors escape try/catch
Returning vs awaitingreturn await preserves stack trace

11. Using AbortController for Cancellation

Example

const ctrl = new AbortController();
setTimeout(() => ctrl.abort(), 5000);
const res = await fetch(url, { signal: ctrl.signal });
APIPurpose
controller.abort(reason?)Trigger cancellation
controller.signalPass to async APIs

12. Using AbortSignal for Timeouts

HelperUse
AbortSignal.timeout(ms)Auto-abort after delay v17.3+
AbortSignal.any([s1, s2])Combine signals v20.3+