Send asynchronous browser requests with fetch, XMLHttpRequest, JSON, errors, and progressive UI.
Lessons
Race a request against a timeout.
Promise.race & Timeouts is easiest to learn by reading the example, changing it, and observing the result.
function timeout(ms) {
return new Promise((_, reject) =>
setTimeout(() => reject(new Error('Request timed out')), ms));
}
const data = await Promise.race([
fetch('/api/lessons').then(r => r.json()),
timeout(5000)
]);Practice the Promise.race & Timeouts example in a small scratch file, then explain what changed and why.