Facebook Pixel

async/await Best Practices in JavaScript

async/await is powerful. Here are the best practices to write clean, efficient async code.

async/await Best Practices in JavaScript

async/await is the cleanest way to write async code. Here are the best practices.

1. Always Handle Errors

async function main() { try { const data = await fetch("/api"); render(data); } catch (err) { handleError(err); } }

2. Use Promise.all for Parallel Operations

const [a, b, c] = await Promise.all([fetchA(), fetchB(), fetchC()]);

3. Use for...of for Sequential await

for (const url of urls) { const data = await fetch(url); process(data); }

4. Do Not Use await in forEach

// bad urls.forEach(async (url) => { await fetch(url); }); // good for (const url of urls) { await fetch(url); }

5. Limit Concurrency for Large Sets

async function batch(items, size, fn) { for (let i = 0; i < items.length; i += size) { await Promise.all(items.slice(i, i + size).map(fn)); } }

6. Use Promise.allSettled for Partial Failure

const results = await Promise.allSettled([fetchA(), fetchB()]); results.forEach((r) => { if (r.status === "fulfilled") handle(r.value); else handleErr(r.reason); });

7. Do Not Fire and Forget

// bad: no error handling fetch("/api"); // good: await and handle await fetch("/api").catch(handleError);

8. Use async/await Over .then Chains

// clean async function main() { const data = await fetch("/api"); const json = await data.json(); render(json); } // less clean fetch("/api").then((data) => data.json()).then((json) => render(json));

9. Use Top-Level await in ES Modules

// module.js (ES module) const data = await fetch("/api"); export default data;

10. Keep async Functions Focused

Each async function should do one thing. Split large functions into smaller ones for readability and testability.

The Takeaway

async/await best practices: always handle errors (try/catch), use Promise.all for parallel, for...of for sequential, never await in forEach, limit concurrency for large sets, use Promise.allSettled for partial failure, do not fire and forget, prefer async/await over .then, use top-level await in ES modules, and keep functions focused.

Always handle errors with try/catch, use Promise.all for parallel operations, for...of for sequential, never await in forEach, limit concurrency for large sets, use Promise.allSettled for partial failure, do not fire and forget, and prefer async/await over .then chains.

Use try/catch around the await calls. If any await rejects, the catch block runs with the rejection reason. try/catch also catches thrown errors inside the try block.

Prefer async/await. It is more readable (looks synchronous), has better stack traces (easier debugging), and works well with loops (for...of with await). Use .then chains only for complex chaining or when async/await is not available.

Batch with Promise.all: process size items at a time. for (let i = 0; i < items.length; i += size) { await Promise.all(items.slice(i, i + size).map(fn)); }. This avoids overwhelming the server or hitting rate limits.

Using await at the top level of an ES module (not inside an async function). Available in ES2022. Useful for initializing modules with async operations. In CommonJS or older environments, wrap in an async function.

Ready to master React completely?

Want to upskill yourself, crack your next interview, and get your dream job? Join our comprehensive course to dive deeper with high-quality video tutorials, solve interview questions, and a premium community.

Please Login.
Please Login.
Please Login.
Please Login.
Please Login.
Please Login.
Please Login.
Please Login.
Please Login.
Please Login.
Please Login.
Please Login.