Courses Learn Blog Contact
Get Started →
Lesson 27

async and await

JavaScript Simplified · One concept, one day, one project · Day 27 of 32 async and await Writing asynchronous code that reads like simple, ordered steps. You build a data loader that waits for a result cleanly. Promises

JavaScript Simplified 3 min read Free

JavaScript Simplified · One concept, one day, one project · Day 27 of 32

async and await

Writing asynchronous code that reads like simple, ordered steps. You build a data loader that waits for a result cleanly.

By the end of today you can

  • Mark a function as async
  • Wait for a Promise with await
  • Handle errors with try and catch
  • Build an async data loader

Promises with .then work, but chains of them can get hard to read. async and await let you write asynchronous code that looks like ordinary, top-to-bottom steps, while still being non-blocking. It is the way modern JavaScript handles "later".

1. async and await

Definition

async in front of a function means it works with Promises and always returns one. Inside an async function, await pauses just that function until a Promise resolves, then gives you its value, as if it had been there all along. The rest of the page keeps running.

What this code doesInside showUser, await getUser() waits for the Promise and hands back the user object. The code reads like three simple steps, even though step two takes a second.
app.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
// a stand-in for a slow server request
function getUser() {
  return new Promise((resolve) => {
    setTimeout(() => resolve({ name: "Ada", role: "student" }), 1000);
  });
}

async function showUser() {
  console.log("Loading user...");
  const user = await getUser(); // wait for the value
  console.log("Loaded: " + user.name + " (" + user.role + ")");
}

showUser();
OUTPUT   TERMINAL
➜ webbo3 node app.js
Loading user...
Loaded: Ada (student)

2. Handling Errors with try/catch

When an awaited Promise rejects, it throws an error. You catch it with try and catch: put the risky await in try, and handle any failure in catch.

What this code doesgetData(false) rejects, so the await throws and the catch runs, printing the problem. try/catch is how you keep an app from breaking when a request fails.
app.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function getData(ok) {
  return new Promise((resolve, reject) => {
    setTimeout(() => ok ? resolve("Here is your data") : reject("Server error"), 800);
  });
}

async function load() {
  try {
    const data = await getData(false); // this one fails
    console.log("Success: " + data);
  } catch (error) {
    console.log("Caught a problem: " + error);
  }
}

load();
OUTPUT   TERMINAL
➜ webbo3 node app.js
Caught a problem: Server error
async/await is Promises, made readable

Under the hood, async/await still uses Promises. It is not a different system, just a cleaner way to write the same thing. Anything with .then can be written with await.

Today’s Mini Project

🔃 Async Data Loader

Simulate loading a profile from a server: show a loading message, await the data, show it, and handle the case where the server fails, all in clean, readable steps.

What this code doesLoading message, await the profile, show it, catch any failure. Three readable steps that are really asynchronous. This is exactly the shape you will use with a real API tomorrow.
app.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
function fetchProfile(username) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      if (username) {
        resolve({ username: username, points: 1240 });
      } else {
        reject("No username given");
      }
    }, 1000);
  });
}

async function loadProfile(username) {
  console.log("Loading profile...");
  try {
    const profile = await fetchProfile(username);
    console.log("Welcome " + profile.username + ", you have " + profile.points + " points.");
  } catch (error) {
    console.log("Could not load profile: " + error);
  }
}

loadProfile("ada");
OUTPUT   TERMINAL
➜ webbo3 node app.js
Loading profile...
Welcome ada, you have 1240 points.
Challenge (15 minutes)

Call loadProfile("") with an empty username and confirm the catch runs, printing "Could not load profile: No username given".

Try This

Rewrite the Day 26 food order .then/.catch using an async function with await and try/catch.

Expected: the same result, written as ordered steps instead of a chain.

Picture This

Asynchronous code used to look alien. Now it reads like a short list of steps: do this, wait for that, then continue, and catch any trouble. You are ready to point this at real data from the internet.

Checkpoint

What does await do?

Inside an async function, it pauses that function until a Promise resolves, then gives you its value. The rest of the page keeps running; only that function waits.

How do you handle an error from an awaited Promise?

With try and catch: put the await in a try block, and handle any failure in the catch block. A rejected Promise throws, and catch receives it.

Is async/await a different system from Promises?

No. It is a cleaner way to write the same thing. Under the hood it still uses Promises; anything with .then can be written with await.

Tick Before You Move On

  • ☐ I can mark a function async
  • ☐ I can wait for a Promise with await
  • ☐ I can handle failures with try and catch
  • ☐ I built the Async Data Loader

Quick Recap

async marks a function that works with Promises. await pauses an async function until a Promise resolves, then returns its value. try/catch handles a rejected Promise without breaking the app. async/await is Promises written as readable, ordered steps.

Next: Day 28. Everything is ready. Tomorrow you make a real request to a real API with fetch, and show live data on the page.

Learn this with a real instructor

Free lessons take you a long way on your own. The full programmes add live classes, assignments, Skill Points and a certificate — built for African students.