Lesson 7 / 11

Asynchronous JavaScript: Promises and async/await

Some operations — fetching data from a server, reading a file — take time to complete. Unlike a normal function call, JavaScript doesn’t pause and wait for these; it hands you a Promise, an object representing a value that will exist eventually, and moves on to run other code in the meantime.

fetch("https://api.example.com/courses")
  .then(response => response.json())
  .then(data => console.log(data))
  .catch(error => console.error(error));

Each .then() runs once the previous step resolves successfully, and receives whatever value that step returned. .catch() runs if anything in the chain fails — a network error, a bad status code you check yourself, or an exception thrown inside any .then().

async/await — the cleaner syntax

async function loadCourses() {
  try {
    const response = await fetch("https://api.example.com/courses");
    const data = await response.json();
    console.log(data);
  } catch (error) {
    console.error(error);
  }
}

await can only be used inside a function marked async. It makes asynchronous code read top-to-bottom like normal synchronous code, which is why most modern JavaScript prefers async/await over chaining .then() calls directly — it doesn’t block the whole browser while waiting, it just pauses that specific function until the Promise settles.

Running multiple requests at once

const [courses, internships] = await Promise.all([
  fetch("/api/courses").then(r => r.json()),
  fetch("/api/internships").then(r => r.json()),
]);

Promise.all runs several async operations in parallel rather than one after another, and waits for all of them to finish. This is significantly faster than await-ing each request individually when they don’t depend on each other’s results.

A common mistake

Forgetting await in front of an async call doesn’t cause an error — it just gives you back the Promise object itself instead of the actual data, which then produces confusing bugs further down your code where you expected a real value. If a variable is unexpectedly showing Promise { <pending> } in the console, you almost certainly forgot an await.