What is a Promise in Javascript? 

Hi, ES5 natively supports 2 patterns for write Asynchronous code, that is, the event pattern and the callback pattern, but in ES6 we have a new pattern for write Asynchronous operations too is called Promise pattern

This new pattern removes the common code issues that the callback (like callback hell) and event pattern had and make the code more readable by developers.

Let’s go into details, a Promise in Javascript is an object and represent an Asynchronous operation, the new Javascript API’s are being purely implemented using Promises.

To create new Promise instances we need to use the Promise constructor:

let promise = new Promise( ) // promise constructor

Then we need to pass a callback function to the Promise constructor, this callback is called executor () => { }.

let promise = new Promise(() => { }) // executor callback

The executor should take two parameters: the resolve and reject callbacks. 

                          // resolve, reject callbacks
let promise = new Promise((resolve, reject) => {}) 

Resolve callback

The resolve callback should be executed if the Asynchronous operation was successful.

 If this callback have a result then we can pass that result to the resolve callback. 

let promise = new Promise((resolve, reject) => {
  let complete = true;

  if (complete) {
    // resolve callback
    resolve('Im the result'); // result
  }
});

Reject callback

The reject callback should be executed if the operation was unsuccessful

If the callback was unsuccessful then we can pass the reason of failure to the reject callback.

let promise = new Promise((resolve, reject) => {
  let complete = false;

  if (complete) {
    // resolve callback
    resolve('Im the result');
  } else {
    // reject callback
    reject('something wrong!'); // result
  }
});

A Promise is always in one of these states:

  • Fulfilled: If the resolve callback is invoked with a non-Promise object  as argument or not argument.
  • Rejected: If the reject callback is invoked or an exception occurs in the executor scope.
  • Settled: If it’s either fulfilled or rejected, but not pending.
  • Pending: If the resolve or reject callback is yet to be invoked.

The fulfillment value in resolve callback 

The fulfillment value of fulfilled Promise represent the result of a successful Asynchronous operation.

resolve( fulfillment value )

If the argument that we passed to the resolved callback is a promise, then the argument itself is considered as a fulfillment value of the first Promise. 

Example: 

// First Promise
let a = new Promise((resolve, reject) => { //

  // Second Promise
  let b = new Promise((res, rej) => {
    rej('Rejected here');
  });

  // The argument is the second Promise
  // The argument itself is considered as a fulfillment  
  // value of the first Promise
  resolve(b); 
});

The .then() method 

Other important part in Promises is the .then() method, this method let us to do some task after a Promise has been fulfilled or rejected. (task can be another event or callback Asynchronous operation).

The .then() method takes two arguments that are callbacks and are executed Asynchronously:

.then(onFulfilled, onRejected)

  • onFulfilled(): callback that is executed if the Promise object was fulfilled (status) and this callback takes a parameter that is the fulfillment value of the Promise.
  • onRejected(): callback that is executed if the Promise object was rejected (status) and this callback takes a parameter that is the reason of rejection.

Example:

let promise = new Promise((resolve, reject) => {

  let complete = false;

  if (complete) {
    // resolve callback
    resolve('result!');
  } else {
    // reject callback
    reject('something wrong!');
  }
});

// onFulfilled() function
const onFulfilled = (value) => { 
  console.log('value ->', value);
}

// onRejected() function
const onRejected = (value) => { 
  console.log('value ->', value);
}

promise // callback functions
  .then(onFulfilled, onRejected); 

We can simplify the code like this:

let promise = new Promise((resolve, reject) => {

  let complete = false;

  if (complete) {
    // resolve callback
    resolve('result!');
  } else {
    // reject callback
    reject('something wrong!');
  }
});


// .then() takes 2 callback functions as parameters
promise
  .then((value) => { // onFulfilled() callback parameter
    console.log('value ->', value);
  }, (value) => { // onRejected() callback parameter
    console.log('value ->', value);
  });

Note: At this point the Status of the promise is resolved and the State is Fulfilled

Don’t be confused with States of the Promise and Status of the Promise.

The .catch() method

If our code is handling only errors and exceptions we can use the .catch() method instead of .then().

Also we can handle the onFulfilled callback in .then() method and onRejected callback in .catch() method. 

There is nothing special of how .catch() method works, the only thing is that makes the code much easier to read.

The .catch() method just take one argument, that is, the onRejected callback. 

Note: the .catch() method always return a Promise. 

Example

let promise = new Promise((resolve, reject) => {

  let complete = false;

  if (complete) {
    // resolve callback
    resolve('result!');
  } else {
    // reject callback
    reject('something wrong!');
  }
});


promise
  .then((value) => { // onFulfilled() in .then method
    console.log('value ->', value);
  })
  .catch((value) => { // onRejected() in .catch method
    console.log('value ->', value);
  });

Flow of a promise

By Cristina Rojas.