Promises - Let's understand how to use them.

Promise Description by MDN Web Docs:

A Promise is a proxy for a value not necessarily known when the promise is created. It allows you to associate handlers with an asynchronous action's eventual success value or failure reason. This lets asynchronous methods return values like synchronous methods: instead of immediately returning the final value, the asynchronous method returns a promise to supply the value at some point in the future.

How do Promises work?

When we are coding, it's not always that we know the values and variables that will be used on the script. At this moment, Promises is an excellent tool to help us to write code that will need parallel results.

The Promise is an action that will be executed in the future of the code and could assume different states:

  • pending: initial state, neither fulfilled nor rejected.
  • fulfilled: meaning that the operation was completed successfully.
  • rejected: meaning that the operation failed.

This way, the .then method will check if a successful(fulfilled) or error(rejected) case exists.

Following the execution flow:

Chaining whit then() and catch()

One of the great things about using promises is chaining.

A Common need is to execute two or more asynchronous operations back to back, where each subsequent operation starts when the previous operation succeeds, with the result from the previous step. We accomplish this by creating a promise chain.

To understand better, let's see the code:

let myFirstPromise = new Promise((resolve, reject) => {
  // We call resolve(...) when what we were doing asynchronously was successful, and reject(...) when it failed.
  // In this example, we use setTimeout(...) to simulate async code.
  // In reality, you will probably be using something like XHR or an HTML5 API.
  setTimeout( function() {
    resolve("Success!")  // Yay! Everything went well!
  }, 250)
})

myFirstPromise.then((successMessage) => {
  // successMessage is whatever we passed in the resolve(...) function above.
  // It doesn't have to be a string, but if it is only a succeed message, it probably will be.
  console.log("Yay! " + successMessage)
});
// output: Yay! Success!

We can combine resolve with then to return success or reject with catch, to fail/error.

Chaining

The then method returns a Promise which allows for method chaining.

If the function passes as a handler to then returns a Promise, an equivalent Promise will be exposed to the subsequent then in the method chain. In the next example, let's see how it can be useful.

const firstElement = array => array[0]
const firstCaracter = string => string[0]
const lowerCase = caracter => caracter.toLowerCase()
new Promise(function(resolve) {
    resolve(["John","Paul","George","Ringo"])
})
    .then(firstElement)
    .then(firstCaracter)
    .then(lowerCase)
    .then(console.log)
// output: j

Here you can see how to use .then in sequence to set up a sequence to explore the data wherever you want.

Now let's go to the last example to show one way to use .catch when the .then doesn't find a valid value:

const fifth = array => array[4]
new Promise(function(resolve) {
    resolve(["John","Paul","George","Ringo"])
})
    .then(fifth)
    .catch(console.log("There Are Only Four"))
// output: There Are Only Four

Thank you for reading.