JS: Promise .prototype .then

By Xah Lee. Date: . Last updated: .

Promise .prototype .then

(new in ECMAScript 2015)

xprom.then(aa,bb)
  • xprom is a promise object.
  • aa and bb are both functions of 1 parameter.
  • aa and bb are optional. if aa or bb are not given, they are not called.
  • aa is typically named on_fulfilled and bb is on_rejected.
  • when the xprom is fulfilled, aa is called with an arg xresult, where xresult is the arg passed to resolve function in the promise executor function body.
  • when the xprom is rejected, bb is called with an arg xerror, where xerror is the arg passed to reject function in the promise executor function body.

The then-method returns a new promise object.

The new promise state is:

  • if aa or bb throws, reject.
  • if aa or bb returns non-promise, fulfill.
  • if aa or bb returns a promise (or thenable), sync state with it.

Example. basic, fully spelled out, showing how it works

const f_executor = (f_resolve, f_reject) => {
 // here is our fake operation that takes long time.
 setTimeout(() => {
  const is_success = Math.random() > 0.5;

  if (is_success) {
   f_resolve("Winning number is 8306");
  } else {
   f_reject("Error number is 7431.");
  }
 }, 500);
};

const f_on_fulfilled = (x) => {
 console.log("fulfilled with value:", x);
};

const f_on_rejected = (x) => {
 console.log("rejected with value:", x);
};

const xpromise = new Promise(f_executor);

xpromise.then(f_on_fulfilled, f_on_rejected);

/*
result.
prints

fulfilled with value: Winning number is 8306

or

rejected with value: Error number is 7431.

*/

Example. on-fulfilled handler only

const xpm = new Promise((aa) => {
 setTimeout(() => aa("Done!"), 500);
});
xpm.then((x) => {
 console.log(x);
});
// Done!

Example. on-reject handler only

note, for on_reject only, you can use Promise.prototype.catch

const xpm = new Promise((good, bad) => {
 setTimeout(() => bad("omg"), 500);
});

xpm.then(
 undefined,
 (x) => {
  console.log("failed value is:", x);
 },
);
// failed value is: omg

Example. then chain

const f_executor = (f_resolve, f_reject) => {
 // always f_resolve
 setTimeout(() => {
  f_resolve("Winning number is 8306");
 }, 500);
};

const on_good = (x) => {
 const throw_dice = Math.random();
 if (throw_dice > 0.5) {
  return x;
 } else {
  // no need to be inside try
  throw (new Error("throw_dice failed. bad luck."));
 }
};

const on_bad = (x) => {
 console.log("Failed. message is:", x);
};

const xpromise = new Promise(f_executor);

xpromise.then(on_good, on_bad).then(
 (x) => {
  console.log("on_good is also good. value is:", x);
 },
 (x) => {
  console.log("on_good got error. value is:", x);
 },
);

console.log("all done.");

/*
result.
prints

all done.
on_good is also good. value is: Winning number is 8306

or
all done.
on_good got error. value is: Error: throw_dice failed. bad luck.
    at on_good ...

*/

Example. on_fulfilled returns a promise

/*
demo. show that in the then method of promise,
if the on_fulfilled returns a promise x,
the return promise of the then method's state, is synced to x.
*/

// create a fulfilled promise
const xpromise = Promise.resolve(3);

// call the then method
const xresult = xpromise.then(
 (x) => {
  return Promise.reject(4);
 },
);

// check the state of the then result
xresult.then(
 (x) => console.log("fulfilled with value:", x),
 (x) => console.log("rejected with value:", x),
);
// rejected with value: 4

Example. on_reject returns a promise

/*
demo. show that in the then method of promise,
if the on_rejected returns a promise x,
the return promise of the then method's state, is synced to x.
*/

// create a rejected promise
const xpromise = Promise.reject(3);

// call the then method
const xresult = xpromise.then(
 // do nothing
 undefined,
 (x) => {
  return Promise.reject(4);
 },
);

// check the state of the then result
xresult.then(
 (x) => console.log("fulfilled with value:", x),
 (x) => console.log("rejected with value:", x),
);
// rejected with value: 4

Reference