JavaScript > Asynchronous JavaScript > Async/Await > Async functions
Fetching Data with Async/Await
This code snippet demonstrates how to use async/await to fetch data from an API. Async/await makes asynchronous code look and behave a little more like synchronous code, which helps in readability and makes the flow of your JavaScript code easier to follow.
Basic Async Function Structure
The async keyword before a function makes it an async function. Inside an async function, the await keyword can be used to pause execution until a promise is resolved. In this case, we're fetching data from a mock API endpoint. await fetch(...) pauses execution until the fetch promise resolves (i.e., the data is received). Then, await response.json() pauses again until the response body is parsed as JSON. The try...catch block handles any potential errors during the process.
async function fetchData() {
try {
const response = await fetch('https://jsonplaceholder.typicode.com/todos/1');
const data = await response.json();
console.log(data);
return data;
} catch (error) {
console.error('Error fetching data:', error);
}
}
fetchData();
Concepts Behind the Snippet
async/await is syntactic sugar built on top of Promises. It simplifies asynchronous code by making it look more like synchronous code. Key concepts include:
async keyword, allowing the use of await.
Real-Life Use Case Section
A common use case for async/await is interacting with APIs, databases, or other external resources that require asynchronous operations. For example, fetching user data from a backend server, submitting a form, or reading files from disk are all situations where async/await can be very helpful.
// Example: Submitting a form using async/await
async function submitForm(formData) {
try {
const response = await fetch('/api/submit', {
method: 'POST',
body: JSON.stringify(formData),
headers: {
'Content-Type': 'application/json'
}
});
const result = await response.json();
console.log('Form submission result:', result);
return result;
} catch (error) {
console.error('Form submission error:', error);
}
}
Best Practices
try...catch blocks to handle potential errors in asynchronous operations.
await inside loops when possible, as it can significantly slow down execution. Use Promise.all() for parallel execution.
Interview Tip
Be prepared to explain how async/await simplifies asynchronous code and how it relates to Promises. Understand the difference between synchronous and asynchronous operations, and why async/await is beneficial for handling asynchronous tasks.
/*
Question: What happens if you don't await a Promise inside an async function?
Answer: The async function will continue executing without waiting for the Promise to resolve. The Promise will still execute asynchronously in the background, but the result won't be used within the function. This is often not the intended behavior.
*/
When to Use Them
Use async/await when you need to work with asynchronous operations in a sequential and readable manner. It's particularly useful when you have multiple asynchronous tasks that depend on each other. It greatly improves code readability compared to Promise chains using .then().
// Example of nested async operations.
async function processData() {
try {
const userData = await fetchUserData();
const posts = await fetchUserPosts(userData.id);
const comments = await fetchPostComments(posts[0].id);
console.log('Comments:', comments);
} catch (error) {
console.error('Error processing data:', error);
}
}
Memory Footprint
Async functions do have a small memory overhead compared to purely synchronous functions. The async/await pattern essentially transforms your code into a state machine that manages the continuation of execution after each awaited promise. However, the overhead is usually negligible for most applications. Optimize when performance becomes a measurable bottleneck.
// Note that the overhead depends more on the async operations involved than the async function itself.
Alternatives
Alternatives to async/await include:
.then() and .catch(): The original way to handle asynchronous operations in JavaScript.
Pros
try...catch blocks.
Cons
await keyword can only be used inside async functions.
await can block the execution of other asynchronous operations. Consider parallel execution with Promise.all() when possible.
FAQ
-
What happens if a promise rejects inside an async function?
If a promise rejects inside anasyncfunction, the error will be caught by the nearesttry...catchblock. If there's notry...catchblock, the rejection will propagate up the call stack. -
Can I use
awaitoutside anasyncfunction?
No, theawaitkeyword can only be used inside functions declared with theasynckeyword. -
How does
async/awaitimprove error handling?
async/awaitallows you to use standardtry...catchblocks for error handling, which is much cleaner and easier to read than the.catch()method used with Promises.