programming foundations30 min

Async Programming

Handling operations that take time: callbacks, promises, and async/await

0/9Not Started

Why This Matters

Most real programs need to wait for things — fetching data from an API, reading a file, querying a database. Asynchronous programming lets your program start a slow operation and continue doing other work while it waits, instead of freezing until the operation completes.

Every web application, mobile app, and server handles async operations. Understanding promises and async/await is essential for building anything that talks to the outside world.

Define Terms

Visual Model

Start task
Promise: pending
Do other work
Waiting...
Resolved (value)
Rejected (error)
.then() handler
.catch() handler
success
failure

The full process at a glance. Click Start tour to walk through each step.

Promises represent future values: pending, then resolved (success) or rejected (error).

Code Example

Code
// Promises: representing future values
const fetchUser = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve({ name: "Alice", age: 28 });
  }, 1000);
});

fetchUser
  .then(user => console.log(user.name))  // Alice (after 1s)
  .catch(err => console.log(err));

// async/await: cleaner syntax for promises
async function getUser() {
  try {
    const response = await fetch("https://api.example.com/user");
    const data = await response.json();
    console.log(data.name);
  } catch (error) {
    console.log("Failed:", error.message);
  }
}

// Promise.all: run multiple async ops in parallel
async function loadDashboard() {
  const [users, posts, stats] = await Promise.all([
    fetch("/api/users").then(r => r.json()),
    fetch("/api/posts").then(r => r.json()),
    fetch("/api/stats").then(r => r.json()),
  ]);
  console.log(users.length, posts.length);
}

// Sequential vs parallel
async function sequential() {
  const a = await slowOp(1);  // wait 1s
  const b = await slowOp(2);  // wait 1s more = 2s total
}
async function parallel() {
  const [a, b] = await Promise.all([
    slowOp(1), slowOp(2)      // both start at once = 1s total
  ]);
}

Interactive Experiment

Try these exercises:

  • Create a promise that resolves with your name after 2 seconds. Chain .then() to print it.
  • Use async/await to call two fake API functions sequentially, then rewrite it with Promise.all.
  • What happens if you await a non-promise value? (Try const x = await 42)
  • Write an async function that intentionally rejects. Handle the error with try/catch.
  • Use Promise.race() to get the result of whichever promise finishes first.

Quick Quiz

Coding Challenge

Async Pipeline

Write an async function called `fetchAndProcess` that: 1) Calls the provided `fetchData()` function (which returns a promise resolving to an array of numbers), 2) Filters out odd numbers, 3) Doubles the remaining even numbers, 4) Returns the sum. Use async/await.

Loading editor...

Real-World Usage

Async programming is the backbone of modern applications:

  • API calls: Every fetch() call to a REST or GraphQL API is async.
  • Database queries: Reading from PostgreSQL, MongoDB, or Redis returns promises.
  • File I/O: Node.js fs.promises makes file operations non-blocking.
  • User interfaces: React state updates after data fetches, loading spinners, optimistic UI.
  • Real-time: WebSocket connections, Server-Sent Events, and polling are all async patterns.

Connections