async/await & Fetch API
async/await makes asynchronous code read like normal top-to-bottom code. The fetch API loads data from URLs — used in browsers and Node (native fetch since Node 18). This is how React apps load data and how Node servers call other APIs.
async function basics
async function loadCourses() {
try {
const res = await fetch('/api/courses');
if (!res.ok) throw new Error('Failed to load');
const courses = await res.json();
return courses;
} catch (err) {
console.error(err);
return [];
}
}
await pauses inside an async function until the Promise completes. It does not block the whole browser — other code still runs.
Parallel requests
async function loadDashboard(userId) {
const [profile, orders] = await Promise.all([
fetch(`/api/users/${userId}`).then(r => r.json()),
fetch(`/api/orders?user=${userId}`).then(r => r.json())
]);
return { profile, orders };
}
🌍 Real-world example — Mark lesson complete (Toolliyo-style)
async function markLessonComplete(slug, csrfToken) {
const res = await fetch('/tutorials/api/progress', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ slug, action: 'complete', csrfToken })
});
const data = await res.json();
return data.success;
}
Same pattern in React: async handler → fetch → update UI state.
⚠️ Common Mistake: Using await inside a non-async function — syntax error. Mark the function async or use .then().
💡 Tip: Always wrap await in try/catch in production — network fails, servers return 500, users go offline.
👨🏫 Teaching note: Demo: fetch a public JSON API (e.g. jsonplaceholder) in browser console with await — instant engagement.