What is a Promise?
By: Andrew Mullan
Tags: JavaScript

Have you ever tried to set the results of a fetch to a variable, but once you run your code the variable does not contain any data you hoped to get back? If you log your variable to the console or check it in a debugger, you may notice your variable’s value is an object called Promise. What exactly is this object?

Per the MDN Web Docs, a “ Promise object represents the eventual completion (or failure) of an asynchronous operation and its resulting value.” The Promise object can have three states: pending, fulfilled, and rejected. The Promise will start in the pending state when it is created, and will eventually change to fulfilled or rejected depending on the result of the function it was given.

A Promise takes in a function, typically one that is asynchronous. This function should have two arguments, one for when the input is resolved and one for when the input is rejected. These functions should be called within the Promise function depending on how you would want it to respond. For example, see the following code:

function myPromise(str){

return new Promise((resolve, reject) => {

if (str === 'Yes'){

resolve('Our Promise was resolved')

} else {

reject('Our Promise was rejected')

}

})

} console.log(myPromise('Yes'))

// logs: Promise {<fulfilled>: "Our Promise was resolved"}

console.log(myPromise('Not Yes'))

// logs: Promise {<rejected>: "Our Promise was rejected"}

In the code example we can see that our function myPromise returns a Promise object. Depending on the value that was passed to the function, the Promise object we received changes. When the function was passed the string ‘Yes’ we went into our if statement and called resolve with the string ‘Our Promise was resolved’ which resulted a Promise who’s state changed to fulfilled and included the string we passed to resolve. When the function was passed ‘Not Yes’ we went into our else statement and called the reject function with ‘Our Promise was rejected’. Because we called the reject function, our returned Promise instead has a state of rejected along with the string passed to reject.

This may seem pointless for a synchronous function like above, but this can be very helpful when it comes to asynchronous functions. Take the following code instead for example:

function myPromise(str){

return new Promise((resolve, reject) => {

function checkString(){

if (str === 'Yes'){

resolve('Our Promise was resolved')

} else {

reject('Our Promise was rejected')

}

}

setTimeout(checkString, 10000)

})

} console.log(myPromise('Yes'))

//logs : Promise {<pending>}

console.log(myPromise('Not Yes'))

//logs : Promise {<pending>}

//10 seconds later logs: Uncaught (in promise) Our Promise was rejected

This time our if/else statements are not checked for 10 seconds, so when calling console.log on our function we originally receive a Promise object who’s state is still pending for both. Then 10 seconds later our myPromise(‘Yes’) call is resolved as well as myPromise(‘Not Yes’). Because we are logging them before it has been fulfilled we do not see the result of myPromise(‘Yes’) and we see the result of the rejection 10 seconds later in myPromise(‘Not Yes’) as an error because it was rejected.

You may be wondering how we can get the result from the previous example when we called myPromise(‘Yes’). If you have used fetch before, then you already have handled how to get promise results and may just not have known it. To get the result of a promise use .then() to receive a resolved value and .catch() to receive a rejected value. If we were to change our console.logs from before to the the code below, we would now see the results of our function calls after the 10 second time out.

myPromise('Yes')

.then(resp => console.log(resp))

myPromise('Not Yes')

.catch(resp => console.log(resp))

// 10 seconds pass...

//logs: Our Promise was resolved

//logs: Our Promise was not resolved

Hopefully this helps clear up what a Promise object is (and maybe even a bit on how fetch works). Further information on all the things a Promise object can do can be found in the MDN Web Docs link in the resources below, however there is one last thing I would like to go over regarding promises and fetch.

One cool thing that Promise can do is wait for multiple asynchronous functions to complete before moving on to the .then() or .catch(). To do this we will use Promise’s .all() method. We pass Promise.all() an array of all of the functions we would like it to wait for and it will return the results in an array. Below is an example of this using fetch (note on the first then we return the resp1.json() and resp2.json() in another Promise.all() and then use another .then() after, this is because the .json() function also returns a Promise):