JavaScript is used to build interactive websites and web applications. Sometimes, we need to perform tasks that take time, such as fetching data from an API, loading user information, or reading a file.
JavaScript provides async and await to make these asynchronous operations easier to write and understand.
In this tutorial, you will learn what async/await is, how it works, and how to use it with simple JavaScript examples.
What Is Async/Await in JavaScript?
Async/await is a modern JavaScript feature that makes working with Promises easier.
It allows you to write asynchronous code in a style that looks similar to normal synchronous code.
There are two keywords:
- async: Declares an asynchronous function that returns a Promise.
- await: Waits for a Promise to settle and evaluates to its fulfilled value, or throws its rejection reason.
1. What Is the async Keyword?
The async keyword is used before a function to make it asynchronous.
Example
async function sayHello() {
return "Hello, World!";
}
sayHello().then((message) => {
console.log(message);
});
Output:
Hello, World!
Even though the function returns a string, an async function wraps the returned value in a Promise.
You can also write the function using an arrow function:
const sayHello = async () => {
return "Hello, World!";
};
2. What Is the await Keyword?
The await keyword pauses the execution of the surrounding async function until a Promise settles. It then returns the fulfilled value or throws an error if the Promise is rejected.
Example
function getData() {
return new Promise((resolve) => {
setTimeout(() => {
resolve("Data loaded successfully!");
}, 2000);
});
}
async function showData() {
const result = await getData();
console.log(result);
}
showData();
Output after approximately 2 seconds:
Data loaded successfully!
In this example:
getData()returns a Promise.await getData()waits for the Promise to settle.- The resolved value is stored in
result. - The message is printed to the console.
The two-second timer is just an example of a delayed operation. The await keyword does not block the entire JavaScript application.
3. Using Async/Await with Fetch API
One of the most common uses of async/await is fetching data from an API.
For example, you can retrieve user information from a public API.
async function getUser() {
const response = await fetch(
"https://jsonplaceholder.typicode.com/users/1"
);
const user = await response.json();
console.log(user);
}
getUser();
This code performs two asynchronous operations:
fetch()sends a request and returns a Promise for the response.response.json()reads and parses the response body.
The user’s data is then printed to the console.
Important: Fetch does not automatically throw an error for HTTP responses such as 404 or 500. Check response.ok when you need to handle unsuccessful HTTP responses.
4. Error Handling with Async/Await
Sometimes, an API request fails because of a network problem or another error. You can handle such errors using try...catch.
Example
async function getUser() {
try {
const response = await fetch(
"https://jsonplaceholder.typicode.com/users/1"
);
if (!response.ok) {
throw new Error("Failed to fetch user data");
}
const user = await response.json();
console.log(user);
} catch (error) {
console.error("Error:", error.message);
}
}
getUser();
In this example:
trycontains the code that might fail.catchhandles errors thrown by the request, response check, or JSON parsing.error.messagedisplays a readable error message.
Using try...catch makes your asynchronous code easier to manage.
5. Difference Between Promises and Async/Await
Async/await is built on top of Promises. Both approaches can handle asynchronous operations, but their syntax is different.
Using Promises
fetch("https://jsonplaceholder.typicode.com/users/1")
.then((response) => response.json())
.then((user) => console.log(user))
.catch((error) => console.error(error));
Using Async/Await
async function getUser() {
try {
const response = await fetch(
"https://jsonplaceholder.typicode.com/users/1"
);
if (!response.ok) {
throw new Error("Request failed");
}
const user = await response.json();
console.log(user);
} catch (error) {
console.error(error);
}
}
getUser();
Both examples retrieve user data. Async/await can make a sequence of asynchronous steps easier to read, especially when error handling is involved.
6. Can We Use Await Without Async?
In regular JavaScript functions, await must be used inside an async function.
async function loadData() {
const result = await Promise.resolve("Hello");
console.log(result);
}
loadData();
However, JavaScript also supports top-level await in ES modules. This means you can use await directly at the top level of a module without wrapping it in an async function.
Conclusion
Async/await makes asynchronous JavaScript easier to read and maintain. It is especially useful when working with APIs, database requests through a backend, and other operations that return Promises.
Remember these key points:
asyncmakes a function return a Promise.awaitwaits for a Promise to settle within the surrounding async function.try...catchhelps handle errors.- Async/await is built on Promises, not a replacement for them.
Practice these examples to understand asynchronous JavaScript before moving on to more advanced topics.
Frequently Asked Questions
1. What is async/await in JavaScript?
Async/await is syntax for working with Promises in a more readable way.
2. Does await block JavaScript?
No. It suspends the surrounding async function while the Promise settles, allowing other JavaScript work to continue.
3. Is async/await better than Promises?
Neither is universally better. Async/await often makes sequential asynchronous operations easier to read, while Promise methods such as Promise.all() are useful for running multiple operations concurrently.
4. Why do we use try…catch with async/await?
We use try…catch to handle rejected Promises and other errors that occur inside the try block.
5. Where is async/await used?
It is commonly used with the Fetch API, server requests, database operations in supported environments, and other asynchronous tasks.