Hey CodingGuru,
Great topic! Async/await is super powerful once you get it. Let's break down your points.
1. Error Handling: This is where try...catch
shines. It works exactly like synchronous error handling.
async function fetchData() {
try {
const response = await fetch('https://api.example.com/data');
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const data = await response.json();
console.log(data);
} catch (error) {
console.error('Failed to fetch data:', error);
}
}
fetchData();
If the fetch
fails or the response is not ok, the catch
block will execute.
2. Concurrent Operations: Use Promise.all()
. You don't await
each promise individually inside the Promise.all
call; you await
the Promise.all
itself.
async function fetchMultiple() {
try {
const [users, posts] = await Promise.all([
fetch('https://api.example.com/users').then(res => res.json()),
fetch('https://api.example.com/posts').then(res => res.json())
]);
console.log('Users:', users);
console.log('Posts:', posts);
} catch (error) {
console.error('Failed to fetch multiple:', error);
}
}
fetchMultiple();
3. await
vs. .then()
: await
pauses the execution of the async
function until the promise resolves or rejects. It returns the resolved value directly. .then()
is the traditional way to handle promise resolution, often leading to "callback hell" or nested structures if not chained carefully.
Example using .then()
(less readable):
function fetchSingleThen() {
fetch('https://api.example.com/data')
.then(response => {
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
return response.json();
})
.then(data => {
console.log(data);
})
.catch(error => {
console.error('Failed to fetch data:', error);
});
}
fetchSingleThen();
async/await
essentially provides a cleaner syntax for the same underlying Promise mechanism.
Common Pitfall: Forgetting to await
inside a loop when processing promises sequentially. If you just map and return promises without awaiting, they'll all start at once.
// Incorrect: This will start all fetches concurrently, not sequentially
async function processSequentiallyBad(ids) {
for (const id of ids) {
const data = await fetch(`https://api.example.com/items/${id}`).then(res => res.json());
console.log(`Processed ${id}:`, data);
}
}
// Correct: Await the Promise.all if you need them done *after* each other conceptually, or just let Promise.all handle concurrency.
async function processConcurrently(ids) {
const promises = ids.map(id => fetch(`https://api.example.com/items/${id}`).then(res => res.json()));
const results = await Promise.all(promises);
console.log('All processed concurrently:', results);
}
Hope this helps!