Async and fetch · Frontend: HTML, CSS and JavaScript
How does a page load data without freezing?
Course contentsWhy you need it
Loading a user's profile or a list of messages means asking a server and waiting, sometimes for seconds. If the page stopped while it waited, nothing could be clicked. JavaScript's answer is asynchronous code: start the request, carry on, and handle the answer when it arrives. Every modern app is built on it.
The intuition
Anything that takes time gives you a Promise: an IOU for a value that will arrive later.
const res = await fetch("https://api.example.com/user/1");
const user = await res.json();- **
fetch(url)** sends an HTTP request and returns a Promise of the response. - **
awaitpauses this function until the Promise settles, without freezing the page. You can only use it inside anasync function**. res.okis true for status 200–299;res.statusis the number. fetch does not throw on 404 or 500, so checkres.ok.res.json()is also a Promise: await it too.- Wrap it in **
try { … } catch (err) { … }** to handle a network failure.
Order matters: ordinary code runs first, then Promise callbacks, then timers.
In this course fetch talks to a pretend API, so your code always gets the same answers.
Definition
Promise
An object standing for a value that isn't ready yet. It ends up fulfilled (with a value) or rejected (with an error).
async / await
async marks a function that can pause; await pauses it until a Promise settles and gives you the value.
fetch
The browser's function for HTTP requests. It resolves with a response for any status; check res.ok yourself.
Examples
Carry on while you wait
Run it in the lessonsetTimeout schedules work for later; the next line runs straight away.
console.log("1: start");
setTimeout(() => console.log("3: timer done"), 1000);
console.log("2: carrying on");1: start 2: carrying on 3: timer done
- L2Schedules a function to run in 1 second, then moves on.
- L3Runs before the timer, even though it comes later in the code.
Fetch a user
Run it in the lessonawait the response, then await its JSON.
async function loadUser(id) {
const res = await fetch(`https://api.example.com/user/${id}`);
const user = await res.json();
return user.name;
}
loadUser(1).then(name => console.log("Hello,", name));
console.log("waiting...");waiting... Hello, Ada
- L2The request goes out; this function pauses here.
- L3The body is JSON; res.json() parses it (and is async too).
- L7Calling an async function returns a Promise; .then runs when it's done.
- L8This prints first: nothing waited for loadUser.
When the server says no
Run it in the lessonA 404 is still a response. Check res.ok.
async function loadUser(id) {
const res = await fetch(`https://api.example.com/user/${id}`);
if (!res.ok) {
return `Error ${res.status}`;
}
const user = await res.json();
return user.name;
}
async function main() {
console.log(await loadUser(2));
console.log(await loadUser(99));
}
main();Linus Error 404
- L3res.ok is false for 404, so we stop here with a message.
- L11await inside main waits for each result in turn.
Two requests at once
Run it in the lessonPromise.all waits for several Promises in parallel.
async function nameOf(id) {
const res = await fetch(`https://api.example.com/user/${id}`);
const user = await res.json();
return user.name;
}
async function main() {
const names = await Promise.all([nameOf(1), nameOf(2)]);
console.log(names);
}
main();[ 'Ada', 'Linus' ]
- L8Both requests start at once; await waits until both have answered.
Common mistakes
Forgetting await
Without await you get the Promise, not the value: res.json is not a function, or Promise { <pending> } in the output.
Not checking res.ok
fetch only rejects when the network fails. A 404 or 500 arrives as a normal response, often with an error body that isn't the data you expect.
Waiting one by one
await a(); await b(); takes the time of both. If they don't depend on each other, await Promise.all([a(), b()]) takes only as long as the slower one.
Quick quiz
1. What does this print?
console.log("A");
setTimeout(() => console.log("B"), 0);
Promise.resolve().then(() => console.log("C"));
console.log("D");Show the answer
Answer: A
Ordinary code first (A, D), then Promise callbacks (C), then timers (B), even a 0 ms timer.
2. The server answers 404 Not Found. What does `await fetch(url)` do?
Show the answer
Answer: A
fetch only fails on network problems. HTTP errors are normal responses: check res.ok.
Practice
3 exercises in three steps: predict what a program prints, change a program to meet a new requirement, then write one from scratch. Your code runs in the browser and is checked the moment you submit.
- PredictOrder of events
Type exactly what this prints, in order.
- ModifyMissing awaits
getName(id)should return the user's name, but it crashes. Fix it. - WriteLoad a profile
Write
async function loadProfile(id)that fetcheshttps://api.example.com/user/<id>and returns:"Ada (London)": the name and city, when the request succeeds"User not found"when the response is not ok (like a 404)"Network error"when fetch itself fails (use try/catch)
Practise this lesson
Open the interactive lesson to edit and run these examples and solve the exercises with instant feedback. Free to start, no sign-up.
Interactive lessons open in order. If you have not done the earlier ones yet, you start at the course map.
Terms in this lesson
| Term | Chinese | Definition |
|---|---|---|
| Promise | Promise | A value that will be ready later, or an error. |
| async / await | async / await | Write asynchronous code that reads top to bottom. |
| fetch | fetch | The browser function for HTTP requests. |