The async keyword is placed before a function declaration. An async function always returns a Promise.
return 5), JavaScript automatically wraps it in a resolved Promise (Promise.resolve(5)).// Standard Function
function getNumber() {
return 5;
}
// returns: 5
// Async Function
async function getAsyncNumber() {
return 5;
}
// returns: Promise { <fulfilled>: 5 }The await keyword can only be used inside an async function.
When the engine encounters await promise:
async function right there.async function fetchData() {
console.log("1. Starting...");
// The function PAUSES here. The CPU goes to do other work.
const data = await fetch("/api/user");
// The function RESUMES here only after data arrives.
console.log("2. Data received:", data);
}It removes the callback structure entirely. We read the code top-to-bottom, just like we read synchronous code, even though time gaps exists between the lines.
try / catch)With Promises, we had to use .catch(). With async/await, we can return to the standard error handling mechanism of JavaScript: the try / catch block.
This unifies error handling for both synchronous and asynchronous errors in a single block.
async function getUser() {
try {
const user = await fetch("/api/user");
const posts = await fetch(`/api/posts/${user.id}`);
console.log(posts);
} catch (error) {
// Catches network errors, 404s, OR syntax errors in the code above
console.error("Something went wrong:", error);
}
}Because await pauses execution, using it inside a loop or sequentially can accidentally kill performance by forcing tasks to run one by one instead of at the same time.
async function getDashboard() {
// Wait 2 seconds
const user = await fetchUser();
// Wait 2 seconds (Total: 4s)
const posts = await fetchPosts();
return { user, posts };
}Why it's bad:
fetchPostsdoesn't needfetchUserto finish. They are independent. We just wasted 2 seconds.
We initiate both promises before awaiting them, or use Promise.all.
async function getDashboard() {
// Start both requests concurrently (Total: 2s)
const userPromise = fetchUser();
const postsPromise = fetchPosts();
// Now we wait for both to finish
const user = await userPromise;
const posts = await postsPromise;
return { user, posts };
}| Feature | Promises (.then) | Async / Await |
|---|---|---|
| Syntax | Chained callbacks | Top-down, imperative |
| Error Handling | .catch() | try / catch |
| Readability | Good (flat chain) | Excellent (looks sync) |
| Engine Behavior | Same (Microtasks) | Same (Microtasks) |
| Pitfall | Callback Hell (if nested) | Accidental Serialization |
Answer:
It is Non-Blocking for the Browser, but Blocking for the code inside the function.
While the async function is paused at the await line, the Browser is free to handle clicks, scroll events, and other scripts. The function yields control back to the engine.