FrontendPrep
Menu
Topics
Questions
Guides
Challenges
Soon
Back to JavaScript Questions
javascriptHard

JavaScript Promises Interview Questions

Master JavaScript Promise interview questions with practical examples. Learn Promise states, chaining, error handling, Promise APIs, async behavior, and how Promises work with the Event Loop.

JavaScript Promises Interview Questions

One of the most frequently asked JavaScript interview questions is:

What is a Promise and why do we need it?

Interviewers often ask:

  • What problems do Promises solve?
  • What are Promise states?
  • How does Promise chaining work?
  • How does Promise error handling work?
  • What is the difference between Promise.all() and Promise.allSettled()?
  • How do Promises interact with the Event Loop?
  • How is async/await related to Promises?

Let's understand Promises from first principles.

1. Why Do We Need Promises?

Before Promises, asynchronous JavaScript was commonly written using callbacks.

Example:

getUser(function (user) {
  getPosts(user.id, function (posts) {
    getComments(posts[0].id, function (comments) {
      console.log(comments);
    });
  });
});

This creates:

Callback Hell

Problems:

  • Deep nesting
  • Difficult error handling
  • Harder debugging
  • Poor readability
  • Difficult composition

Promises were introduced to make asynchronous code more manageable.

2. What is a Promise & Its States

A Promise is an object that represents the eventual completion or failure of an asynchronous operation.

Think of a Promise as:

A Placeholder
For A Future Value

Example:

const promise = fetch("/users");

At this moment:

Data Is Not Available Yet

The Promise represents the future result.

Real-Life Analogy

Imagine ordering food online.

Order Placed

Food Being Prepared

Delivered

A Promise works similarly:

Pending

Fulfilled
or
Rejected

Promise States

Every Promise exists in one of three states.

Pending

Operation Still Running

Fulfilled

Operation Completed Successfully

Rejected

Operation Failed

Visual Representation

         Pending
        /       \
       /         \
Fulfilled      Rejected

A Promise can change state only once.

3. Creating a Promise

Example:

const promise = new Promise((resolve, reject) => {
  const success = true;
 
  if (success) {
    resolve("Success");
  } else {
    reject("Failed");
  }
});

Resolve

resolve(value);

Marks the Promise as:

Fulfilled

Reject

reject(error);

Marks the Promise as:

Rejected

4. Consuming a Promise & Error Handling

promise.then((result) => {
  console.log(result);
});

Output:

Success

Handling Errors

promise.catch((error) => {
  console.error(error);
});

Output:

Failed

Complete Example

const promise = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve("Data Loaded");
  }, 1000);
});
 
promise.then((data) => {
  console.log(data);
});

Output after 1 second:

Data Loaded

5. Promise Chaining & Flow Visualization

One of the biggest advantages of Promises.

Example:

fetchUser()
  .then((user) => {
    return fetchPosts(user.id);
  })
  .then((posts) => {
    return fetchComments(posts[0].id);
  })
  .then((comments) => {
    console.log(comments);
  });

Instead of:

Nested Callbacks

we get:

Linear Flow

How Chaining Works

Every:

.then()

returns a new Promise.

Example:

Promise.resolve(5)
  .then((value) => {
    return value * 2;
  })
  .then((value) => {
    console.log(value);
  });

Output:

10

Promise Chain Visualization

Promise

then()

then()

then()

Each step receives the previous result.

Error Handling in Chains

Example:

fetchUser()
  .then((user) => {
    throw new Error("Failed");
  })
  .catch((error) => {
    console.log(error.message);
  });

Output:

Failed

Why This Is Powerful

A single:

.catch()

can handle errors from the entire chain.

Example:

task1().then(task2).then(task3).catch(handleError);

Much cleaner than nested callbacks.

6. Execution Order & Event Loop Priority

What is the output?

console.log("Start");
 
const promise = new Promise((resolve) => {
  console.log("Inside");
 
  resolve();
});
 
console.log("End");

Answer

Output:

Start
Inside
End

Important:

Promise Constructor Executes Immediately

Many developers incorrectly assume it is asynchronous.

Event Loop Interview Question

What is the output?

console.log("1");
 
Promise.resolve().then(() => {
  console.log("2");
});
 
console.log("3");

Answer

Output:

1
3
2

Why?

.then()

creates a:

Microtask

Microtasks execute after synchronous code completes.

Promise vs setTimeout

What is the output?

console.log("1");
 
setTimeout(() => {
  console.log("2");
}, 0);
 
Promise.resolve().then(() => {
  console.log("3");
});
 
console.log("4");

Answer

Output:

1
4
3
2

Why?

Execution order:

Sync Code

Microtasks

Macrotasks

Promises use:

Microtask Queue

Timers use:

Macrotask Queue

7. Parallel Promises: Promise.all vs. allSettled vs. race vs. any

Runs multiple Promises concurrently.

Example:

Promise.all([fetchUsers(), fetchPosts(), fetchComments()]);

Behavior:

Wait For All

Example

Promise.all([Promise.resolve("A"), Promise.resolve("B")]).then((result) => {
  console.log(result);
});

Output:

["A", "B"]

Promise.all Failure Behavior

Promise.all([Promise.resolve("A"), Promise.reject("Error")]);

Output:

Rejected

One failure rejects the entire Promise.

Promise.allSettled()

Waits for all Promises regardless of success or failure.

Example:

Promise.allSettled([Promise.resolve("A"), Promise.reject("Error")]);

Output:

[
  {
    status: "fulfilled",
    value: "A",
  },
  {
    status: "rejected",
    reason: "Error",
  },
];

Promise.race()

Returns the first settled Promise.

Example:

Promise.race([fetchUsers(), timeout()]);

Useful for request timeouts.

Promise.any()

Returns the first fulfilled Promise.

Example:

Promise.any([api1(), api2(), api3()]);

Success from any source wins.

Promise.finally()

Runs regardless of success or failure.

Example:

fetchData()
  .then(handleSuccess)
  .catch(handleError)
  .finally(() => {
    hideLoader();
  });

Useful for cleanup.

8. Promises vs. Async/Await

Promise:

fetchUser()
  .then((user) => {
    return fetchPosts(user.id);
  })
  .then(console.log);

Async/Await

const user = await fetchUser();
 
const posts = await fetchPosts(user.id);
 
console.log(posts);

Cleaner syntax.

Important Interview Point

Async/Await:

Does Not Replace Promises

Instead:

Built On Top Of Promises

9. Common Interview Q&A

Can a Promise Change State Twice?

No.

Example:

resolve("A");
resolve("B");
reject("Error");

Only the first state change matters.

Does Creating a Promise Make It Asynchronous?

No.

The Promise constructor executes immediately.

What Queue Do Promise Callbacks Use?

Microtask Queue

What Happens If a Then Callback Returns a Promise?

The next .then() waits for that Promise to settle.

What Happens If a Then Callback Throws?

The Promise becomes rejected.

The error propagates to the nearest .catch().

Senior-Level Interview Answer

A Promise is an object that represents the eventual completion or failure of an asynchronous operation. It can be in one of three states: pending, fulfilled, or rejected. Promises solve callback hell by providing a structured way to compose asynchronous operations through chaining. Methods such as then, catch, and finally allow success handling, error handling, and cleanup. Promise callbacks are scheduled in the Microtask Queue, which gives them higher priority than timer callbacks in the Event Loop. Modern async/await syntax is built on top of Promises and provides a cleaner way to write asynchronous code.

Common Interview Mistakes

❌ "Promises are asynchronous."

Correct:

Promise callbacks are asynchronous.
The Promise constructor executes immediately.

❌ "Async/Await replaces Promises."

Correct:

Async/Await is built on top of Promises.

❌ "Promise.all waits even if one Promise fails."

Correct:

Promise.all rejects immediately
when any Promise rejects.

❌ "Promises use the Callback Queue."

Correct:

Promises use the Microtask Queue.

Promise API Summary

APIBehavior
Promise.resolve()Creates fulfilled Promise
Promise.reject()Creates rejected Promise
Promise.all()Waits for all Promises
Promise.allSettled()Waits for all results
Promise.race()First settled Promise wins
Promise.any()First fulfilled Promise wins
finally()Runs regardless of outcome

Key Takeaways

  • Promise States: A Promise represents an async operation that exists in one of three states: pending, fulfilled, or rejected.
  • Chaining: Methods like then and catch return new Promises, preventing nesting and resolving callback hell.
  • Event Loop Priority: Promise callbacks are processed inside the Microtask Queue, prioritizing them over standard timers.
  • Parallel APIs: Use Promise.all for parallel operations, and Promise.allSettled to fetch resources without cascading failures.

Share this Resource

Help other developers level up by sharing this study guide.

More Technical Questions

Expand your mastery. Deep dive into other frontend interview challenges in this category.