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 anasync
function, the error will be caught by the nearesttry...catch
block. If there's notry...catch
block, the rejection will propagate up the call stack. -
Can I use
await
outside anasync
function?
No, theawait
keyword can only be used inside functions declared with theasync
keyword. -
How does
async/await
improve error handling?
async/await
allows you to use standardtry...catch
blocks for error handling, which is much cleaner and easier to read than the.catch()
method used with Promises.