100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace
Node.js

Promises in Node.js

Understanding the Promise object and its pending, fulfilled, and rejected states for cleaner async code.

Asynchronous ProgrammingIntermediate10 min readJul 8, 2026
Analogies

Introduction

A Promise is an object representing the eventual completion or failure of an asynchronous operation. Promises were introduced to solve callback hell by providing a chainable, more predictable structure for async code. Every Promise exists in one of three states: pending (initial state, operation not yet complete), fulfilled (operation completed successfully, with a resulting value), or rejected (operation failed, with a reason/error). Once a Promise settles (fulfilled or rejected), its state and value are immutable.

🏏

Cricket analogy: A Promise is like a DRS review request: it's pending while the third umpire checks replays, fulfilled if the decision confirms the appeal with a result, or rejected if overturned with a reason, and once the decision is given it never changes again.

Syntax

javascript
const promise = new Promise((resolve, reject) => {
  const success = true;
  if (success) {
    resolve('Operation succeeded');
  } else {
    reject(new Error('Operation failed'));
  }
});

promise
  .then((result) => console.log(result))
  .catch((error) => console.error(error))
  .finally(() => console.log('Done'));

Explanation

The Promise constructor takes an executor function with resolve and reject parameters. Calling resolve(value) transitions the Promise from pending to fulfilled and passes value to any .then() handlers. Calling reject(reason) transitions it to rejected, triggering .catch() handlers. The .then() method returns a new Promise, enabling chaining: each .then() callback's return value (or thrown error) determines the next Promise's state. .finally() runs regardless of outcome, useful for cleanup like closing a database connection.

🏏

Cricket analogy: resolve(value) is like the third umpire signaling 'out' and passing the replay evidence to the commentary team (.then() handlers), while reject(reason) signals 'not out' with the reasoning; .finally() is like the ground staff resetting the pitch cover regardless of the verdict.

Example

javascript
function fetchUser(id) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      if (id > 0) resolve({ id, name: 'Alice' });
      else reject(new Error('Invalid id'));
    }, 500);
  });
}

function fetchOrders(userId) {
  return new Promise((resolve) => {
    setTimeout(() => resolve(['order1', 'order2']), 500);
  });
}

fetchUser(42)
  .then((user) => {
    console.log('User:', user.name);
    return fetchOrders(user.id);
  })
  .then((orders) => console.log('Orders:', orders))
  .catch((err) => console.error('Error:', err.message));

// Combining multiple independent promises
Promise.all([fetchUser(1), fetchUser(2)])
  .then((users) => console.log('All users:', users));

Output

After ~500ms: 'User: Alice' logs, then after another ~500ms 'Orders: [ 'order1', 'order2' ]' logs, because returning a Promise from a .then() callback chains it — the next .then() waits for it to settle. If fetchUser rejected (e.g., id <= 0), the chain would skip directly to .catch(), printing 'Error: Invalid id'. Promise.all resolves once all input promises fulfill, or rejects immediately if any one rejects.

🏏

Cricket analogy: This chained sequence is like a broadcast delaying the player-profile graphic by 500ms after confirming the batsman's name, then another 500ms before showing the strike-rate stats, and if the player ID was invalid, it skips straight to an 'unknown player' error graphic instead.

Key Takeaways

  • A Promise has exactly one of three states: pending, fulfilled, or rejected, and settles only once.
  • resolve() fulfills a Promise; reject() rejects it, both are immutable after settling.
  • Returning a value or Promise inside .then() chains cleanly instead of nesting callbacks.
  • A thrown error or rejected Promise anywhere in the chain is caught by the nearest .catch().
  • Promise.all, Promise.race, Promise.allSettled, and Promise.any coordinate multiple Promises differently.

Practice what you learned

Was this page helpful?

Topics covered

#NodeJs#NodeJsExpressStudyNotes#WebDevelopment#PromisesInNodeJs#Promises#Node#Syntax#Explanation#StudyNotes#SkillVeris