JavaScript Async/Await: A Complete Guide
Master modern asynchronous JavaScript with async/await syntax
Introduction
Async/await is the modern way to handle asynchronous operations in JavaScript. Built on top of promises, it provides a cleaner, more readable syntax that looks synchronous while remaining non-blocking.
What is Async/Await?
async and await are keywords that make asynchronous code look and behave like synchronous code.
// Traditional promise-based code
function getUser() {
return fetch('/api/user')
.then(response => response.json())
.then(data => data);
}
// Modern async/await syntax
async function getUser() {
const response = await fetch('/api/user');
const data = await response.json();
return data;
}
The async Keyword
Adding async before a function makes it return a promise automatically.
async function hello() {
return 'Hello!';
}
hello().then(console.log); // 'Hello!'
The await Keyword
await can only be used inside async functions. It pauses execution until a promise settles.
async function fetchData() {
const response = await fetch('/api/data');
const data = await response.json();
return data;
}
Error Handling
Use try/catch blocks to handle errors:
async function getUser() {
try {
const response = await fetch('/api/user');
const data = await response.json();
return data;
} catch (error) {
console.error('Failed to fetch user:', error);
throw error;
}
}
Parallel Execution
Use Promise.all() for parallel execution:
// ❌ Sequential (slow)
async function getData() {
const user = await fetchUser();
const posts = await fetchPosts();
const comments = await fetchComments();
}
// ✅ Parallel (fast)
async function getData() {
const [user, posts, comments] = await Promise.all([
fetchUser(),
fetchPosts(),
fetchComments()
]);
}
Real-World Examples
API Calls
async function createUser(userData) {
const response = await fetch('/api/users', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(userData)
});
if (!response.ok) throw new Error('Failed');
return await response.json();
}
Retry Logic
async function fetchWithRetry(url, retries = 3) {
for (let i = 0; i < retries; i++) {
try {
const response = await fetch(url);
if (response.ok) return response;
} catch (error) {
if (i === retries - 1) throw error;
await new Promise(resolve => setTimeout(resolve, 1000));
}
}
}
Common Pitfalls
Forgetting await
// ❌ Missing await
async function getData() {
const data = fetch('/api/data'); // Returns Promise!
}
// ✅ Correct
async function getData() {
const data = await fetch('/api/data');
}
Sequential When Parallel Is Possible
// ❌ Slow
const a = await getA();
const b = await getB();
// ✅ Fast
const [a, b] = await Promise.all([getA(), getB()]);
Best Practices
- Always handle errors with try/catch
- Use Promise.all for independent operations
- Keep async functions focused
- Document async behavior
Conclusion
Async/await makes asynchronous JavaScript more readable and maintainable. Master it to write cleaner, more efficient async code.
#javascript #async #promises