JavaScript · The language round

How do async and await work, and how do you handle errors?

MediumasyncawaiterrorsUpdated Oct 2026
Quiz this track

Short answer

An async function always returns a promise. await pauses that function until the awaited promise settles, and a rejected promise becomes a thrown error that try/catch can handle.

async and await are syntax over promises. They make asynchronous code read sequentially without changing the underlying event-loop behaviour.

js
async function loadUser(id) {
  try {
    const response = await fetch("/api/users/" + id);

    if (!response.ok) {
      throw new Error("HTTP " + response.status);
    }

    return await response.json();
  } catch (error) {
    console.error(error);
    throw error;
  }
}

What await actually does

  • It pauses the current async function, not the whole thread
  • Other code and other tasks continue while the promise is pending
  • The function resumes in a microtask after the promise settles
  • A resolved value is returned; a rejection is thrown at the await line

Independent awaits run sequentially. If two requests do not depend on each other, start both and await them together with Promise.all.

js
const [user, posts] = await Promise.all([
  fetch("/api/user").then((response) => response.json()),
  fetch("/api/posts").then((response) => response.json()),
]);

Do not pass an async callback to forEach and expect it to wait. forEach ignores the returned promises. Use for...of for sequential work or Promise.all with map for parallel work.

An async function that throws returns a rejected promise. If nobody awaits it, the rejection can become unhandled.

Follow-ups you should expect

Interviewers use these to check whether the first answer was understanding or memorisation.

  1. 1Does `await` block the entire thread?
  2. 2How do you run two requests in parallel?
  3. 3Why does `forEach` not wait for async callbacks?
  4. 4What happens to a thrown error inside an async function?

Say it in the interview

An async function always returns a promise. await pauses only that function until the awaited promise settles, while the rest of the program keeps running. A rejection is thrown at the await line, so try/catch handles it like a synchronous error. Independent awaits should be started together with Promise.all. And I avoid async callbacks in forEach because forEach does not wait for them.

Use this as a model, not a script. Saying it in your own words is what makes it survive follow-up pressure.

Related questions

Reading is step one

Now say it out loud.

Understanding an answer and delivering it under pressure are different skills. Rehearse this topic in a live JavaScript mock interview and get scored feedback on depth, clarity and confidence.