JavaScript Promises

A Promise is an object that represents the eventual completion (or failure) of an asynchronous operation and its resulting value. Promises provide a cleaner alternative to callbacks for handling asynchronous code.

Creating a Promise

A Promise is created using the new Promise() constructor. It takes a function (executor) with two parameters: resolve (called on success) and reject (called on failure).

new Promise()
const myPromise = new Promise(function(resolve, reject) {
  const success = true;

  if (success) {
    resolve('Operation succeeded!');
  } else {
    reject('Operation failed!');
  }
});

console.log(myPromise);
console.log(typeof myPromise);

resolve and reject

When an async operation succeeds, call resolve() with the result value. When it fails, call reject() with the error. A promise can only be resolved or rejected once.

Resolve and Reject
function checkAge(age) {
  return new Promise(function(resolve, reject) {
    if (age >= 18) {
      resolve('Access granted. Age: ' + age);
    } else {
      reject('Access denied. Must be 18+.');
    }
  });
}

checkAge(20).then(function(message) {
  console.log(message);
});

checkAge(15).catch(function(error) {
  console.log(error);
});

.then(), .catch(), and .finally()

The .then() method handles the resolved value, .catch() handles rejections/errors, and .finally() runs regardless of the outcome. These methods return new promises, enabling chaining.

then, catch, finally
function fetchUser(id) {
  return new Promise(function(resolve, reject) {
    if (id > 0) {
      resolve({ id: id, name: 'User ' + id });
    } else {
      reject('Invalid user ID');
    }
  });
}

fetchUser(1)
  .then(function(user) {
    console.log('Found: ' + user.name);
  })
  .catch(function(error) {
    console.log('Error: ' + error);
  })
  .finally(function() {
    console.log('Operation complete');
  });

Promise Chaining

Since .then() returns a new promise, you can chain multiple .then() calls together. Each .then() receives the result of the previous .then() as its argument.

Chaining Promises
function double(value) {
  return new Promise(function(resolve) {
    resolve(value * 2);
  });
}

double(5)
  .then(function(result) {
    console.log('First: ' + result);
    return double(result);
  })
  .then(function(result) {
    console.log('Second: ' + result);
    return double(result);
  })
  .then(function(result) {
    console.log('Third: ' + result);
  });

Promise Static Methods

Promise provides several static methods for working with multiple promises: Promise.all(), Promise.race(), Promise.allSettled(), and Promise.any().

MethodResolves whenRejects when
Promise.all()All promises resolveAny promise rejects
Promise.race()First promise settlesFirst promise rejects
Promise.allSettled()All promises settleNever rejects
Promise.any()Any promise resolvesAll promises reject
Promise.all() and Promise.race()
const p1 = Promise.resolve('One');
const p2 = Promise.resolve('Two');
const p3 = Promise.resolve('Three');

// Promise.all - waits for all
Promise.all([p1, p2, p3]).then(function(values) {
  console.log('All: ' + values);
});

// Promise.race - first to settle
Promise.race([p1, p2, p3]).then(function(value) {
  console.log('Race winner: ' + value);
});

// Promise.allSettled - all results
const p4 = Promise.reject('Error!');
Promise.allSettled([p1, p4]).then(function(results) {
  results.forEach(function(r) {
    console.log(r.status + ': ' + (r.value || r.reason));
  });
});
📝 Note: A promise is in one of three states: pending (initial state), fulfilled (operation completed successfully), or rejected (operation failed). Once a promise is fulfilled or rejected, it is settled and its state cannot change.
Exercise:
What does Promise.all() do when one of the promises rejects?
Try it YourselfCtrl+Enter to run
Click Run to see the output here.