CodeMIRAI
0 XP

async and await

2 min read 4 runnable examples Quiz included

async and await are a cleaner way to work with promises. Code waits for results in order, like normal code, without blocking the page.

Call stackmain()loadUser()console.log()Browser / Node APIstimers, fetch, eventsdo the waitingMicrotasks: promisesTasks: setTimeoutstartEventloopwhen the stack is empty: all microtasks first, then the next task
JavaScript runs one thing at a time. Waiting happens outside the stack; finished work queues up, promises first, and runs when the stack is clear.
JavaScript
const wait = (ms) => new Promise((r) => setTimeout(r, ms));

async function makeTea() {
  console.log("Boiling water...");
  await wait(400);
  console.log("Steeping...");
  await wait(400);
  console.log("Tea is ready!");
  return "a cup of tea";
}

makeTea().then((result) => console.log("Got:", result));
console.log("(the page isn't frozen while we wait)");
  • async function always returns a promise.
  • await pauses that function until the promise settles, then gives you its value.

Error handling with try/catch

JavaScript
function login(user, password) {
  return new Promise((resolve, reject) =>
    setTimeout(() => (password === "secret" ? resolve({ user }) : reject(new Error("Wrong password"))), 200)
  );
}

async function signIn(user, password) {
  try {
    const session = await login(user, password);
    console.log(`Welcome, ${session.user}!`);
  } catch (err) {
    console.log("Sign-in failed:", err.message);
  } finally {
    console.log("(done)");
  }
}

await signIn("asha", "secret");
await signIn("leo", "guess");

A rejected promise behaves like a thrown error inside an async function, so ordinary try/catch handles it.

Sequential vs parallel

Each await waits for the one before it. When tasks don't depend on each other, start them together with Promise.all:

JavaScript
const job = (name, ms) => new Promise((r) => setTimeout(() => r(name), ms));

let t = Date.now();
await job("a", 300);
await job("b", 300);
console.log(`one after another: ~${Date.now() - t} ms`);

t = Date.now();
const results = await Promise.all([job("a", 300), job("b", 300)]);
console.log(`together: ~${Date.now() - t} ms`, results);

Top-level await

In modules (and in CodeMIRAI's runner) you can use await outside a function, as the examples above do. In older scripts, await only works inside an async function.

Looping with await

JavaScript
const fetchScore = (name) => new Promise((r) => setTimeout(() => r(name.length * 10), 100));

const names = ["Asha", "Leo", "Mei"];
for (const name of names) {
  const score = await fetchScore(name);       // one at a time, in order
  console.log(name, score);
}
Finished this lesson?Mark it complete to earn +20 XP and move your progress on.