JavaScript Async/Await Interview Questions
One of the most commonly asked JavaScript interview questions is:
What are async/await and how do they work?
Most developers can write:
async function fetchUsers() {
const users = await getUsers();
}But interviewers often go deeper:
- Is async/await different from Promises?
- Does await block the main thread?
- How does await interact with the Event Loop?
- Can multiple awaits run in parallel?
- What happens when an error occurs?
Let's understand async/await from first principles.
1. Why Do We Need Async/Await?
Consider fetching user data from an API.
Using callbacks:
getUser(function (user) {
getPosts(user.id, function (posts) {
getComments(posts[0].id, function (comments) {
console.log(comments);
});
});
});This quickly becomes:
Callback HellProblems:
- Hard to read
- Hard to debug
- Difficult error handling
- Nested code
Promises improved this:
getUser()
.then(getPosts)
.then(getComments)
.then(console.log)
.catch(console.error);Better, but still chain-heavy.
Async/await was introduced to make asynchronous code look synchronous.
2. What is an Async Function?
The async keyword transforms a function into an asynchronous function.
async function greet() {
return "Hello";
}Although it appears to return a string:
greet();actually returns:
Promise { "Hello" }Equivalent to:
function greet() {
return Promise.resolve("Hello");
}Example
async function getMessage() {
return "FrontendPrep";
}
console.log(getMessage());Output:
Promise { "FrontendPrep" }Important interview point:
Every async function always returns a Promise.
3. What is Await?
await pauses execution inside an async function until a Promise settles.
Example:
async function fetchData() {
const data = await getUsers();
console.log(data);
}Execution flow:
Call Function
↓
Wait For Promise
↓
Promise Resolves
↓
Continue ExecutionSimple Example
function delay() {
return new Promise((resolve) => {
setTimeout(() => {
resolve("Done");
}, 2000);
});
}
async function run() {
const result = await delay();
console.log(result);
}
run();Output after 2 seconds:
DoneDoes Await Block JavaScript?
A common interview question.
Many developers answer:
YesThis is incorrect.
Wrong
await blocks JavaScriptCorrect
await pauses only the current async functionThe Event Loop continues running.
Example:
async function demo() {
console.log("Start");
await Promise.resolve();
console.log("End");
}
demo();
console.log("Outside");Output:
Start
Outside
EndIf await blocked JavaScript:
Start
End
Outsidewould appear.
It doesn't.
4. Async/Await Under the Hood
Consider:
async function getUser() {
const user = await fetch("/api/user");
return user.json();
}JavaScript roughly converts this into:
function getUser() {
return fetch("/api/user").then((user) => {
return user.json();
});
}Important interview point:
Async/await is syntax sugar over Promises.
Execution Order Interview Question
What is the output?
console.log(1);
async function demo() {
console.log(2);
await Promise.resolve();
console.log(3);
}
demo();
console.log(4);Answer
Output:
1
2
4
3Why?
1 → Sync
2 → Sync
await → Pause function
4 → Sync
3 → Microtask Queue5. Error Handling with Async/Await
Promises:
fetchData().then(handleSuccess).catch(handleError);Async/Await:
async function loadData() {
try {
const data = await fetchData();
console.log(data);
} catch (error) {
console.error(error);
}
}Cleaner and easier to read.
What Happens When Await Rejects?
async function demo() {
await Promise.reject("Failed");
}Equivalent to:
throw "Failed";The function immediately exits unless handled.
Example
async function demo() {
try {
await Promise.reject("Error");
console.log("Never runs");
} catch (error) {
console.log(error);
}
}Output:
Error6. Optimization: Sequential vs. Parallel Awaits
Consider:
const user = await getUser();
const posts = await getPosts();Execution:
Get User
↓
Wait
↓
Get Posts
↓
WaitTotal time:
Time1 + Time2Interview Optimization Question
What is wrong here?
const users = await fetchUsers();
const posts = await fetchPosts();If both requests are independent:
Unnecessary waitingBetter Solution
const [users, posts] = await Promise.all([fetchUsers(), fetchPosts()]);Execution:
Start Both Requests
↓
Wait Once
↓
Receive ResultsTotal time:
max(Time1, Time2)instead of:
Time1 + Time2Async/Await vs Promise.all
Sequential
await task1();
await task2();
await task3();Timeline:
Task1
↓
Task2
↓
Task3Concurrent
await Promise.all([task1(), task2(), task3()]);Timeline:
Task1
Task2
Task3
↓
Wait OnceMuch faster.
7. Top-Level Await
No.
Invalid:
function demo() {
const data = await fetchUsers();
}Error:
await is only valid in async functionsTop-Level Await
Modern JavaScript allows:
const users = await fetchUsers();inside ES modules.
Example:
// users.js
const users = await fetch("/users");
export default users;8. Async Function Execution Without Await
async function demo() {
return 10;
}Perfectly valid.
Output:
Promise { 10 }9. Common Interview Q&A
Does Async/Await Replace Promises?
No.
Async/await is built on top of Promises.
Promises still power everything underneath.
Does Await Create a New Thread?
No.
JavaScript remains single-threaded.
The Event Loop handles scheduling.
Can Multiple Awaits Run Simultaneously?
Not automatically.
This:
await task1();
await task2();runs sequentially.
Use:
Promise.all();for concurrency.
Can Async Functions Return Values?
Yes.
async function getName() {
return "John";
}Actually returns:
Promise.resolve("John");What Happens If an Async Function Throws?
async function demo() {
throw new Error("Failed");
}Equivalent to:
return Promise.reject(new Error("Failed"));Senior-Level Interview Answer
Async/await is syntactic sugar built on top of Promises that allows asynchronous code to be written in a synchronous-looking manner. An async function always returns a Promise, and the await keyword pauses execution of the current async function until a Promise settles. Await does not block the JavaScript thread; it simply yields control back to the Event Loop. Under the hood, async/await is transformed into Promise chains. For independent asynchronous operations, Promise.all should be used to execute tasks concurrently and improve performance.
Common Interview Mistakes
❌ "await blocks JavaScript."
Correct:
await pauses only the current async function.❌ "async functions return values."
Correct:
async functions always return Promises.❌ "async/await is different from Promises."
Correct:
async/await is built on top of Promises.❌ "Multiple awaits run in parallel."
Correct:
Awaits are sequential unless explicitly parallelized.Key Takeaways
- Syntactic Sugar: Built on top of Promises to write cleaner, synchronous-looking asynchronous code.
- Execution Flow: An
asyncfunction returns a Promise;awaitpauses execution until the Promise resolves. - Error Handling: Uses native
try/catchblocks instead of.catch()chains for asynchronous operations. - Task Orchestration: Awaiting tasks sequentially can block execution; use
Promise.allto run requests in parallel. - Top-Level Await: Supported in modern modules to pause importing modules until assets resolve.