Stop 02 · Node.js FundamentalsTopics · 8/18

Async Programming

Part of the Backend Developer Roadmap

In short

A backend spends most of its life waiting: for the database, for other APIs, for the disk. Async programming lets you wait for many things at once instead of one after another.

The general practice of writing code that doesn't block while waiting for slow operations (I/O, network, timers) — essential to Node's entire performance model.

The mascot hands a bundle of clothes to a dhobi and walks off towards class with a backpack.

Think of it like this

Giving clothes to the dhobi

You don't stand at the dhobi's while he washes. You drop the clothes, go to class, and collect them later. Even better, drop the clothes, order books and book a cycle repair together, then pick everything up in the evening. Start, move on, collect: that's async.

Watch it happen

Building a dashboard response

Client
Handler
Database
Weather API

GET /dashboard

1/6The response needs two things: the user's data and today's weather.

The big ideas

What you need to know

Sync waits, async doesn't

Synchronous code stops until each step finishes. Async code starts a task and gets notified when it's done.

Three styles, one idea

Callbacks came first, then promises, then async/await. Under the hood, modern code is promises all the way.

Parallel when independent

If two calls don't need each other's results, start both and wait for both with Promise.all.

Errors still need a home

A rejected promise with no handler crashes modern Node. Catch errors where you await.

See it in code

Walk through the code

js
1const wait = (ms, value) => new Promise((r) => setTimeout(() => r(value), ms));2const getUser = () => wait(120, { name: "Asha" });3const getWeather = () => wait(200, { temp: 31 });4 5console.time("one by one");6const u1 = await getUser();7const w1 = await getWeather();8console.timeEnd("one by one"); // about 320 ms9 10console.time("together");11const [u2, w2] = await Promise.all([getUser(), getWeather()]);12console.timeEnd("together"); // about 200 ms13 14console.log(u2.name, w2.temp);

1/3Two fake slow calls, standing in for a database query and an API request.

Save as async.mjs and run it with node. Use Promise.all only when the calls don't depend on each other's results.

Save yourself the pain

Common mistakes

Oops

Awaiting independent calls one after another, especially inside a loop.

Do this instead

Start them together and await Promise.all. Await in sequence only when a step needs the previous result.

Oops

Starting async work and never handling its error.

Do this instead

An unhandled promise rejection crashes modern Node. Await it inside try/catch, or attach .catch().

Your mission

Speed up a slow handler

~20 min

Quick check

getUser takes 100 ms and getOrders takes 300 ms, and neither needs the other. How long does await Promise.all([getUser(), getOrders()]) take?

Go deeper

  1. 1Identify 3 asynchronous operations in a typical backend request (DB query, API call, file read).
  2. 2Compare how the same async task looks with callbacks, Promises, and async/await.
  3. 3Learn common async pitfalls: unhandled rejections, forgetting to await.

More topics at this stop

Stuck on this topic? Ask an Insider

Get 1:1 guidance from people who've walked this exact path — on the InsideEdge app.

Download
InsideEdge