Interview Q&A / JavaScript

BeginnerIn-depth3 min readUpdated 2 Oct 2026

What is the difference between promises and async/await, and how do you handle errors with each?

SHORT ANSWER

async/await is cleaner syntax built on top of promises. An async function always returns a promise, and await pauses that function until a promise settles. With promises you handle errors using .catch(); with async/await you use try/catch around the await.

Explain it simply

When you order food online, the app gives you an order ID immediately, even though the food arrives later. That order ID is a promise: a placeholder for a value that will come in the future. It can end in one of two ways: fulfilled (food delivered) or rejected (order cancelled). Until then it is pending.

With plain promises, you write what should happen next using .then() for success and .catch() for failure. With async/await, you write the same steps as if they were normal top-to-bottom code. await means "wait here for this promise, then continue with its value". Under the hood it is still promises. It is not a different mechanism, just easier to read.

Example

The same task written both ways: fetch a user, then their orders.

js
// With promise chains
function showOrders(userId) {
  return getUser(userId)
    .then((user) => getOrders(user.id))
    .then((orders) => console.log("Orders:", orders.length))
    .catch((err) => console.log("Failed:", err.message))
    .finally(() => console.log("Done"));
}

// With async/await
async function showOrdersAsync(userId) {
  try {
    const user = await getUser(userId);
    const orders = await getOrders(user.id);
    console.log("Orders:", orders.length);
  } catch (err) {
    console.log("Failed:", err.message);
  } finally {
    console.log("Done");
  }
}

Running independent work in parallel:

js
async function loadDashboard() {
  // Slow: the second request waits for the first.
  // const profile = await getProfile();
  // const offers = await getOffers();

  // Faster: both start together.
  const [profile, offers] = await Promise.all([getProfile(), getOffers()]);
  return { profile, offers };
}

How it works

  • An async function always returns a promise. Returning a value fulfils it; throwing an error rejects it.
  • await pauses only that async function. The rest of the program keeps running; the code after await resumes later as a microtask (see the event loop).
  • If the awaited promise rejects, await throws, so a normal try/catch can catch it.
  • A .catch() at the end of a chain catches a rejection from any earlier step.

Useful helpers:

HelperResolves whenRejects when
Promise.allall succeedany one fails
Promise.allSettledall finish, success or failurenever
Promise.racethe first one settlesthe first one to settle fails
Promise.anythe first one succeedsall fail

Real-world use

Calling APIs, reading files in Node, querying databases, and waiting for a UPI payment status are all asynchronous. Most modern codebases use async/await for readability and use Promise.all or Promise.allSettled when several calls can happen at once.

Common mistakes

  • Forgetting await, so you get a pending promise instead of the data.
  • Awaiting independent calls one after another, which makes the total time the sum of all calls.
  • Using await inside forEach. It does not wait. Use for...of or Promise.all with map.
  • Leaving a promise without any .catch() or try/catch, which causes unhandled rejections.
  • Wrapping a promise in new Promise unnecessarily.

What to say in the interview

"A promise represents a future value and is pending, fulfilled or rejected. async/await is syntax on top of promises: an async function returns a promise, and await pauses that function until the promise settles, then gives me its value or throws its error. With promise chains I handle errors with .catch(), and with async/await I use try/catch. I prefer async/await for readability, but I still use Promise.all when calls are independent, so they run in parallel instead of one after another."

Follow-up questions

  • What is the output order if you mix await, setTimeout and console.log?
  • What is the difference between Promise.all and Promise.allSettled?
  • Can you use await at the top level of a file?

Go deeper

Read these once the basics above feel easy.

return await matters inside try/catch: return promise inside a try block hands the promise straight to the caller, so if it rejects, your catch does not run. return await promise waits first, so the rejection is caught locally. Top-level await is allowed in ES modules (and therefore in modern browsers with type="module" and in Node ESM files), but not in classic scripts or CommonJS.

#promises#async-await#async#error-handling

Related questions

Practise more JavaScript questions

Test your recall with short answers, then return to the detailed explanations when you need context.

Open JavaScript quick answers →

Get new questions like this by email

One short email when something new and useful lands. No spam, unsubscribe in one tap.

By subscribing you agree to the Privacy Policy.