JavaScript Async/Await Interview Questions & Answers

4 interview angles 3 min read source

JavaScript Async/Await Interview Questions & Answers

Async/await is a modern syntax for working with Promises in JavaScript, making asynchronous code look and behave more like synchronous code. It greatly improves readability and error handling.

Table of Contents


What is async/await?

  • async and await are keywords introduced in ES2017 (ES8) to simplify working with Promises.
  • An async function always returns a Promise.
  • The await keyword pauses the execution of an async function until the Promise settles (fulfilled or rejected).

Example:

async function fetchData() {
  return 'data';
}

fetchData().then(result => console.log(result)); // 'data'

How to use async/await

Basic usage:

function delay(ms) {
  return new Promise(resolve => setTimeout(resolve, ms));
}

async function run() {
  console.log('Start');
  await delay(1000);
  console.log('After 1 second');
  await delay(1000);
  console.log('After 2 seconds');
}

run();

Awaiting a Promise:

async function getData() {
  const result = await Promise.resolve('Hello');
  console.log(result); // 'Hello'
}

Returning values:

async function add(a, b) {
  return a + b;
}

add(2, 3).then(result => console.log(result)); // 5

Error Handling

  • Use try...catch blocks inside async functions to handle errors.
  • If a Promise is rejected, await throws the error.
async function fetchWithError() {
  try {
    const result = await Promise.reject('Oops!');
    console.log(result); // Won't run
  } catch (error) {
    console.error('Caught:', error); // 'Caught: Oops!'
  }
}

fetchWithError();

Sequential vs Parallel Execution

Sequential (one after another):

async function sequential() {
  await delay(1000);
  await delay(1000);
  // Takes 2 seconds total
}

Parallel (at the same time):

async function parallel() {
  const p1 = delay(1000);
  const p2 = delay(1000);
  await Promise.all([p1, p2]);
  // Takes 1 second total
}

Common Pitfalls

  • Forgetting to use await (returns a Promise instead of the value)
  • Using await outside of an async function (SyntaxError)
  • Not handling errors with try/catch
  • Running async operations sequentially when they could be parallel

Interview Questions

  1. What does the async keyword do?
    • Declares a function that always returns a Promise.
  2. What does the await keyword do?
    • Pauses execution in an async function until the Promise settles.
  3. How do you handle errors in async/await?
    • Use try/catch blocks inside async functions.
  4. Can you use await outside of an async function?
    • No, it throws a SyntaxError.
  5. How do you run async operations in parallel with async/await?
    • Start Promises first, then await Promise.all([...]).
  6. What happens if you forget to use await?
    • The function returns a Promise instead of the resolved value.
  7. How do you convert a callback or promise-based function to async/await?
    • Wrap it in an async function and use await.
  8. What is the difference between sequential and parallel execution with async/await?
    • Sequential waits for each to finish, parallel starts all and waits for all.

Additional Resources


Async/await makes asynchronous code easier to write, read, and debug. Master it for modern JavaScript interviews!

Interview angle

  • “What does async/await actually do?” - syntax over promises. An async function always returns a promise; await suspends the function until the awaited promise settles, without blocking the thread.
  • “What is the most common performance mistake?” - awaiting inside a loop when the calls are independent, which serialises them. Start them all and await Promise.all(...), or use for await only when order genuinely matters.
  • “How do you handle errors?” - try/catch around the await. An async function that throws produces a rejected promise, so a call without await or .catch becomes an unhandled rejection - which in Node terminates the process by default.
  • “What is top-level await?” - awaiting at module scope in an ES module. It delays the module’s evaluation and that of every importer, so it is fine for config loading and dangerous in a hot path.