asyncfunctionloadUser(userId){const response =awaitfetch(`/api/users/${userId}`);if(!response.ok){thrownewError(`HTTP ${response.status}`);}const user =await response.json();return user;}// Usagetry{const user =awaitloadUser(42);console.log(user.name);}catch(err){console.error("Failed to load user:", err.message);}
Note await pauses execution inside an async function until the promise settles. Top-level await works in ES modules. Always handle errors with try/catch or .catch().
async awaitawait promiseasync functionasynchronous function
Note Runs all promises in parallel and resolves when ALL succeed. Rejects immediately if ANY promise rejects -- other pending promises are not cancelled, just ignored.
parallel promisesPromise.allconcurrent requestswait for all
Note Never rejects. Each result is { status: "fulfilled", value } or { status: "rejected", reason }. Use when you want all results regardless of failures.
functionfetchWithTimeout(url, ms =5000){const timeout =newPromise((_, reject)=>setTimeout(()=>reject(newError("Timeout")), ms));returnPromise.race([fetch(url), timeout]);}try{const response =awaitfetchWithTimeout("/api/data",3000);console.log(await response.json());}catch(err){console.error(err.message);// "Timeout" or network error}
Note Settles as soon as the first promise settles (fulfilled OR rejected). Common use: implementing timeouts.
promise racefirst to finishtimeout promisefastest promise
Promise.any()
Syntax
Promise.any([p1, p2, p3])
Example
asyncfunctionfetchFromMirrors(path){returnPromise.any([fetch(`https://mirror1.example.com${path}`),fetch(`https://mirror2.example.com${path}`),fetch(`https://mirror3.example.com${path}`),]);}// Returns the first successful response; ignores individual failures
Note Resolves with the first fulfilled promise. Only rejects if ALL promises reject (with an AggregateError). The opposite of Promise.race() for error handling.
// GET requestconst res =awaitfetch("/api/products");const products =await res.json();// POST requestconst created =awaitfetch("/api/products",{
method:"POST",
headers:{"Content-Type":"application/json"},
body:JSON.stringify({ name:"Widget", price:29.99}),});if(!created.ok)thrownewError(`HTTP ${created.status}`);
Note fetch() does NOT reject on HTTP error status codes (404, 500). Always check response.ok or response.status. The body can only be consumed once.
asyncfunctionsearchWithCancel(query){const controller =newAbortController();// Auto-cancel after 5 secondsconst timeoutId =setTimeout(()=> controller.abort(),5000);try{const res =awaitfetch(`/api/search?q=${query}`,{
signal: controller.signal,});clearTimeout(timeoutId);returnawait res.json();}catch(err){if(err.name==="AbortError"){console.log("Request was cancelled");}else{throw err;}}}
Note Essential for cancelling stale requests (e.g., in search-as-you-type). The AbortSignal can be shared across multiple fetch calls to cancel them all at once.
// Wrapper to avoid repetitive try/catchasyncfunctionsafeAwait(promise){try{const data =await promise;return[data,null];}catch(err){return[null, err];}}const[user, error]=awaitsafeAwait(fetch("/api/me").then(r => r.json()));if(error){console.error("Failed:", error.message);}else{console.log("User:", user.name);}
Note Unhandled promise rejections crash Node.js and show warnings in browsers. Always catch async errors. The tuple pattern [data, error] is popular for cleaner control flow.