- Array() find
- -- operator
- -= operator
- ++ operator
- += operator
- Accessing and setting content
- AND operator
- Array concat() method
- Array indexOf()
- Array length
- Array pop()
- Array shift
- Array slice() method
- Arrays
- Async await
- Booleans
- Braces
- Callback function
- Calling the function
- Class
- Closure
- Code block
- Comment
- Conditions
- Console
- Constructor
- Creating a p element
- Data types
- Date getTime()
- Destructuring
- Else
- Else if
- Enum
- Environment
- Equals operator
- Error Handling
- ES6
- Event loop
- Events
- Extend
- Fetch API
- Filter
- For loop
- forEach()
- Function
- Function bind()
- Function name
- Greater than
- Head element
- Hoisting
- If statement
- includes()
- Infinity property
- Iterator
- JSON
- Less than
- Local storage
- Map
- Methods
- Module
- Numbers
- Object
- Object.keys()
- Overriding methods
- Parameters
- Promises
- Prototype
- Random
- Reduce
- Regex
- Regular expressions
- Removing an element
- Replace
- Scope
- Session storage
- setTimeout() method
- Sleep() function
- Sort
- Splice
- String
- String concat()
- String indexOf()
- String slice() method
- Substring
- Switch statement
- Template literals
- Ternary operator
- throw Statement
- Title
- Type conversion
- void Operator
- While loop
JAVASCRIPT
JavaScript Async Await: Syntax, Usage, and Examples
JavaScript async await syntax allows asynchronous code to look and behave more like synchronous code. Introduced in ES2017, async/await simplifies working with Promises and makes your code easier to read, write, and debug — especially in complex workflows involving API calls, timers, or file access.
How to Use JavaScript Async Await
To use async await JavaScript provides, start by defining a function with the async
keyword. Inside that function, use await
to pause execution until a Promise resolves or rejects.
Here’s the basic pattern:
async function fetchData() {
const response = await fetch("https://api.example.com/data");
const data = await response.json();
console.log(data);
}
async
marks a function as asynchronous. It always returns a Promise.await
pauses the function’s execution until the Promise on the right resolves.- You can only use
await
insideasync
functions (or in the top level of supported environments like modern browsers or Node.js with ES modules).
The result: cleaner, flatter code without .then()
chains or nested callbacks.
When to Use Async Await in JavaScript
1. Chaining Multiple Asynchronous Operations
When you need to perform one async task after another, async and await in JavaScript simplify the flow. For example, you may want to:
- Fetch user data
- Then fetch posts based on that user
- Then render both in the UI
Using async/await, the logic is sequential and readable.
2. Reducing Callback Complexity
Async/await helps flatten callback hell — the pyramid of nested functions that occurs with traditional asynchronous code. This makes the program easier to follow and less error-prone.
3. Handling API Errors Gracefully
You can wrap await
calls in try/catch
blocks to catch errors just like synchronous code, making error handling consistent and intuitive.
async function safeFetch() {
try {
const response = await fetch("https://bad.url");
const data = await response.json();
console.log(data);
} catch (error) {
console.error("Fetch failed:", error);
}
}
This is much easier to manage than nested .catch()
chains.
Examples of Async Await JavaScript Usage
1. Sequential API Requests
async function loadDashboard() {
const user = await fetch("/api/user").then(res => res.json());
const stats = await fetch(`/api/stats/${user.id}`).then(res => res.json());
console.log("User:", user);
console.log("Stats:", stats);
}
Each await
waits for the previous call to complete before continuing.
2. Running Asynchronous Functions in Parallel
Sometimes you don’t need to wait for each task to finish before starting the next. You can launch Promises simultaneously, then await
them together with Promise.all()
.
async function getData() {
const userPromise = fetch("/api/user");
const postsPromise = fetch("/api/posts");
const [userRes, postsRes] = await Promise.all([userPromise, postsPromise]);
const user = await userRes.json();
const posts = await postsRes.json();
console.log("User:", user);
console.log("Posts:", posts);
}
This pattern improves performance by allowing multiple tasks to run concurrently.
3. Handling Rejected Promises
async function riskyOperation() {
try {
const result = await fetch("/api/broken-endpoint");
const json = await result.json();
console.log(json);
} catch (error) {
console.error("Something went wrong:", error.message);
}
}
You can use try/catch
to handle rejections just like you would handle errors in regular synchronous code.
Learn More About Async Await in JavaScript
What Is Async Await in JavaScript Exactly?
Async/await in JavaScript is syntactic sugar over Promises. It doesn’t replace Promises — it enhances how you work with them.
async
functions always return a Promise. Even if you return a plain value, it will be wrapped in a resolved Promise.await
pauses the execution of theasync
function until the Promise is settled (either resolved or rejected).
This model helps simplify asynchronous control flow, especially when dealing with multiple dependent operations.
How Async Functions Work Behind the Scenes
When you call an async
function, it runs until the first await
, pauses, and schedules the rest of the function to run when the awaited Promise resolves. This happens through the microtask queue in the JavaScript runtime.
console.log("Start");
async function test() {
console.log("Inside function");
await Promise.resolve();
console.log("After await");
}
test();
console.log("End");
// Output:
// Start
// Inside function
// End
// After await
The message After await
runs after the main thread finishes executing, because the await
pauses execution and lets the event loop continue.
Mixing Async Await with Traditional Promises
You can freely combine async functions with .then()
:
async function fetchAndLog() {
await fetch("/api/data")
.then(res => res.json())
.then(data => console.log(data))
.catch(err => console.error(err));
}
This can be useful when working with third-party libraries that return Promises.
However, mixing styles too much can reduce readability. Prefer consistent use of await
in async
functions unless you have a specific reason to use .then()
chains.
Using Async Await in Loops
When using await
inside loops, be aware that it pauses the loop on each iteration:
const urls = ["/a", "/b", "/c"];
async function fetchAll() {
for (const url of urls) {
const res = await fetch(url);
const data = await res.json();
console.log(data);
}
}
This pattern is simple but inefficient if the requests don’t depend on each other. For parallel processing, use Promise.all()
or map()
with await
.
async function fetchAllFast() {
const results = await Promise.all(urls.map(url =>
fetch(url).then(res => res.json())
));
console.log(results);
}
This version runs all requests at the same time and waits for all to finish.
Top-Level Await
In modern environments that support ES modules, you can use await
at the top level without wrapping it in a function.
// example.mjs
const response = await fetch("/api/data");
const data = await response.json();
console.log(data);
This works in:
- ES modules in modern browsers
.mjs
files in Node.js- Some interactive shells like Deno or browser DevTools
Top-level await
makes quick scripts cleaner, but for compatibility, many production environments still use async
functions.
Returning Values from Async Functions
Async functions return Promises, so you need to use await
or .then()
to access their results.
async function getNumber() {
return 42;
}
getNumber().then(console.log); // Output: 42
Or use await
inside another async function:
async function caller() {
const num = await getNumber();
console.log(num); // Output: 42
}
If you forget to await, you’ll log a Promise object instead of the value you expected.
Error Handling Best Practices
Some useful patterns for handling errors:
- Global try/catch:
async function load() {
try {
const data = await fetchData();
display(data);
} catch (e) {
showError("Could not load data.");
}
}
- Fail early with custom errors:
if (!userToken) {
throw new Error("Missing user token");
}
- Graceful degradation with fallback values:
const data = await fetchData().catch(() => ({ fallback: true }));
Handling async errors well helps avoid crashes and improves user experience.
Async/Await and Event Handlers
In frontend development, it’s common to use async functions in response to user actions:
document.querySelector("#button").addEventListener("click", async () => {
try {
const data = await fetch("/api/data").then(res => res.json());
console.log(data);
} catch (e) {
console.error("Error loading data:", e);
}
});
Because event listeners can run async functions, you can keep UI interactions clean and responsive while still using asynchronous logic behind the scenes.
JavaScript async await offers a cleaner, more readable alternative to Promise chaining and callback-based code. You use async
to define functions that return Promises, and await
to pause execution until a Promise resolves. This pattern shines when dealing with sequential API calls, file operations, timers, or any task that relies on asynchronous events.
Sign up or download Mimo from the App Store or Google Play to enhance your programming skills and prepare for a career in tech.