Async/Await in JavaScript
async
and await
simplify asynchronous programming by allowing asynchronous code to look like synchronous code while still being non-blocking.
async Keyword
- Declares a function as asynchronous.
- Always returns a Promise.
- Returning a value automatically wraps it in
Promise.resolve
. - Throwing an error returns a rejected Promise.
Example:
async function greet() {
return "Hello";
}
greet().then(console.log); // Output: "Hello"
// Equivalent to:
function greet() {
return Promise.resolve("Hello");
}
await Keyword
- Pauses execution until the Promise resolves.
- Returns the resolved value or throws an error if the Promise rejects.
- Can only be used inside async functions.
Example:
async function myDisplay() {
let myPromise = new Promise(resolve => resolve("I love You !!"));
let value = await myPromise;
console.log(value); // Output: "I love You !!"
}
myDisplay();
Examples of Practical Usage
a) Waiting for a Timeout:
async function delayedMessage() {
let message = await new Promise(resolve => setTimeout(() => resolve("Hello after 3s"), 3000));
console.log(message);
}
delayedMessage();
b) Fetching Files (XMLHttpRequest):
async function getFile() {
let myPromise = new Promise(resolve => {
let req = new XMLHttpRequest();
req.open("GET", "mycar.html");
req.onload = () => resolve(req.status === 200 ? req.response : "File not Found");
req.send();
});
console.log(await myPromise);
}
getFile();
c) Modern Fetch Alternative:
async function getFile() {
try {
const response = await fetch("mycar.html");
const text = await response.text();
console.log(response.ok ? text : "File not Found");
} catch (error) {
console.error("Error:", error.message);
}
}
getFile();
Error Handling
Always wrap await
in try/catch
blocks to catch rejected Promises.
async function myDisplay() {
try {
let myPromise = new Promise((resolve, reject) => {
setTimeout(() => reject(new Error("Failed")), 1000);
});
console.log(await myPromise);
} catch (error) {
console.error("Error:", error.message);
}
}
myDisplay();
Best Practices
Use try/catch for error handling
async function example() {
try {
const data = await fetch("<https://invalid-url>").then(res => res.json());
} catch (error) {
console.error("Failed:", error);
}
}
Parallel Execution with Promise.all
async function fetchMultiple() {
const [data1, data2] = await Promise.all([
fetch("<https://api1.example.com>").then(res => res.json()),
fetch("<https://api2.example.com>").then(res => res.json())
]);
console.log(data1, data2);
}
Avoid sequential await in loops for performance
// Sequential (slower)
for (const url of urls) {
const data = await fetch(url).then(res => res.json());
}
// Parallel (faster)
const promises = urls.map(url => fetch(url).then(res => res.json()));
const results = await Promise.all(promises);
results.forEach(data => console.log(data));
Top-Level Await (ES2022+)
// In a module
const data = await fetch("<https://api.example.com/data>").then(res => res.json());
console.log(data);
Cleanup Resources
async function fetchWithTimeout(url, ms) {
const controller = new AbortController();
const timeout = setTimeout(() => controller.abort(), ms);
try {
const response = await fetch(url, { signal: controller.signal });
clearTimeout(timeout);
return await response.json();
} catch (error) {
console.error(error);
}
}