An introduction to Promises
Published: 2021-03-01 07:34:51

![Alt Text](https://1.bp.blogspot.com/-enABL0nGe_o/WVfnFP372ZI/AAAAAAAAAdI/DRyxjETrcQ07QxBQHbiT4FqkoOVrcb_OwCLcBGAs/s1600/Screen%2BShot%2B2017-07-01%2Bat%2B2.16.29%2BPM.png)

### What are Promises? 
Promises let us create asynchronous code that is a lot easier to read and understand, and a lot less repetitive to write. 
MDN Web Docs says "A promise is an object that represents the eventual completion or failure of a asynchronous operation". 
It is a way of promising a value that you do not possess at the moment that promise is made. 

### How to create a promise ... 

A promise is a returned object to which you attach callbacks, instead of passing callbacks into a function. 

Here is an example of a new Promise saved to a variable named myNewPromise ... 
```
const myNewPromise = new Promise((resolve ,reject) => {

}); 
```
When we create a Promise we pass in a function. This function will always accept two parameters, 'resolve' , and 'reject'. 
Both of these parameters are actually functions. if the resolve() function is called our promise will be resolved. If the reject() function is called then our promise will be rejected. 

By examining myNewPromise in the dev console ...

```
myNewPromise
Promise {<pending>}
    __proto__: Promise
    [[PromiseState]]: "pending"
    [[PromiseResult]]: undefined
```
you can see that its status at the moment is pending. 
Notice that it has one property set to promise state and that it is currently pending. A promise will remain pending by default until it is either reject or fulfilled. If we are making a request and it takes 5 seconds then the response we get back will be pending, until that 5 seconds is over and we are given response in the form of data. 

So if we execute one of the functions in the the parameters of the Promise 'reject' or 'resolve', we will get a corresponding answer for each. 
```
const myNewPromise = new Promise((resolve ,reject) => {
    resolve(); 
}); 
```
Notice how if we pass in resolve then we look at myNewPromise in the dev console we will see that it is no longer pending. 
```
Promise {<fulfilled>: undefined}
__proto__: Promise
[[PromiseState]]: "fulfilled"
[[PromiseResult]]: undefined
```
The promise has been fulfilled. 

### How to interact with Promises ...

Every promise has a .then() method and a .catch() method. These methods are chained to the function call and execute at run time. 
Below we created a myNewPromise function that uses Math.random() to randomly decide if our Promise will be resolved or rejected. We have also chained on a .then() and a .catch() method to the end of our function call.

```
 const myNewPromise = new Promise((resolve, reject) => {
    const rand = Math.random(); 
    if ( rand < 0.5 ) {
        resolve(); 
    } else {
        reject(); 
    }

}).then(() => {
    console.log("the promise was fulfilled"); 
}).catch(() => {
    console.log("your promise was rejected Dx")
}) 
```
The Promise function is executed and if the Promise is resolved then our .then() method will execute and the message "the promise was fulfilled" will be logged to our console. If the Promise is rejected, the .catch() method will be executed and we will get "your promise was rejected Dx" logged to the console. 

### Rejecting or Resolving with a value

We use promises when we want to send a requests to the Api. This request will generally take time so we use Promises. The point of these requests is to usually get some sort of data back. 
When you reject or resolve a promise you can reject or resolve it with a value, obtaining access to that value in your callback. That value gets passed into the .then() or .catch() methods which is very useful because we usually want to know why something was rejected. If it is resolved then we want to be able to access the data that we get back. 

So lets demonstrate that by writing a fake request to the server. 
```
const ourRequest = (url) => {
    return new Promise((resolve, reject) => {
        setTimeout(() => {

                 const pages = {
                    '/users' : [
                        {id: 1, username: "Hannah"},
                        {id: 5, username: "Beth"}
                    ],
                    "/about" : "this is the about page"
                }; 
                const data = pages[url];    
                if(data){
                    resolve({status: 202, data}); 
                }
                else {
                    reject({status: 404}); 
                }
            
        }, 1000); 
    }); 
}; 

ourRequest("/users")
.then((response) => {
    console.log(`${response.status}`);
    console.log('Data', response.data)
    console.log("REQUEST WORKED!"); 
})
.catch((response) => {
    console.log(response.status); 
    console.log("REQUEST FAILED")
})

```
Above we have a function ourRequest() that returns a new Promise. It takes in a url. Its going to take some amount of time before we get a response back from our server. For this we have implemented a setTimeOut() function. 
For reject we have passed in a status code that is a object with a key of status and a value of 404. We have added a response parameter to our .catch that will catch and log 
our response.
For resolve we have passed in a status code that is a object with a key of status and a value of 202, and a object with a key of data and a value of data.
When we call ourRequest() if the url we pass into the request matches the url in our data then our Promise is resolved and we get access to the data we have requested. 

This has been a quick introduction to understanding promises. To understand more in depth uses for Promises more i recommend taking a look at Promise Chaining.