Interview answer drill

Use this JavaScript interview question to rehearse a quick answer, common mistake, follow-up, and production pitfall.

Promises and async/awaitFrontend interview answer

HighIntermediateJavascript
Interview focus

This JavaScript interview question tests whether you can explain Promises vs async await: concurrency, stale-request control, and production pitfalls, connect it to production trade-offs, and handle common follow-up questions.

  • Promises vs async await: concurrency, stale-request control, and production pitfalls explanation without falling back to memorized docs wording
  • Async Await and Concurrency reasoning, edge cases, and production failure modes
  • How you would answer the most likely JavaScript interview follow-up
Practice more JavaScript interview questions
Interview quick answer

Promises and async/await use the same async model, but production decisions are really about concurrency, stale-request cancellation, request identity, and error boundaries rather than syntax alone.

Full interview answer

Short version

A Promise represents a future result. async/await is a cleaner way to consume Promises. Same engine behavior, different readability style, but the production pitfall is assuming await is always clearer when it may accidentally serialize independent work. A strong production answer usually shows both independent work started together and one stale-request guard, because syntax is not the hard part.

Question

Answer

Do async functions return Promises?

Yes, always.

Does await block the whole app?

No. It pauses only that async function.

Does await change event-loop priority?

No. Promise continuation still resumes as microtasks.

Three interview checks people often confuse.
JAVASCRIPT
function fetchUser(id) {
  return Promise.resolve({ id, name: 'Ada' });
}

// Promise style
fetchUser(1)
  .then(user => user.name)
  .then(name => console.log(name))
  .catch(console.error);

// async/await style
async function run() {
  try {
    const user = await fetchUser(1);
    console.log(user.name);
  } catch (err) {
    console.error(err);
  }
}
run();
                  

Most important practical rule: avoid accidental serialization

JAVASCRIPT
// ❌ Sequential (slow if independent)
const a = await fetch('/a').then(r => r.json());
const b = await fetch('/b').then(r => r.json());

// ✅ Parallel (faster)
const [a2, b2] = await Promise.all([
  fetch('/a').then(r => r.json()),
  fetch('/b').then(r => r.json())
]);
                  

Need

Preferred API

Why

All must succeed

Promise.all

Fast-fails on first rejection.

Need every outcome

Promise.allSettled

Get success+failure results together.

First success wins

Promise.any

Useful for fallback mirrors/CDNs.

First settled wins

Promise.race

Timeout or first-responder patterns.

Choose combinator by business behavior, not habit.
JAVASCRIPT
let activeController;
let latestRequestId = 0;

async function loadDashboard(userId) {
  activeController?.abort();
  const controller = new AbortController();
  activeController = controller;
  const requestId = ++latestRequestId;

  try {
    const [profile, notifications] = await Promise.all([
      fetch(`/api/profile/${userId}`, { signal: controller.signal }).then(r => r.json()),
      fetch(`/api/notifications/${userId}`, { signal: controller.signal }).then(r => r.json())
    ]);

    if (requestId !== latestRequestId) return; // stale result guard
    renderDashboard({ profile, notifications });
  } catch (err) {
    if (err.name === 'AbortError') return;
    reportError(err);
  }
}
                  

Why this pattern wins in production

Start independent requests together, keep one try/catch boundary, and pair AbortController with a request-identity guard when older work must never overwrite newer UI state.

Practical scenario
Autocomplete requests fire on each keystroke. You debounce input, cancel stale requests, and only render the latest resolved result to avoid flicker and race bugs.

Common pitfalls

  • Using await inside loops when calls are independent.
  • Forgetting terminal error handling.
  • Assuming Promise cancellation exists automatically.

Still so complicated?

Promise is the contract for future data. await is just cleaner punctuation when reading that contract.

Summary
  • Promises and async/await are the same async model.
  • Use try/catch (or .catch) consistently.
  • Parallelize independent work with Promise.all.
  • Use cancellation for stale UI requests.
Similar questions
Guides
Preparing for interviews?

Use this as one explanation rep, then continue with the JavaScript interview questions cluster or a guided prep path.