Promises in Javascript Explained + Examples
Tags: javascript, promises, webdev
Published: 2021-02-01 10:29:06

### Prerequisites

Before you begin this tutorial you'll need the following:

- IDE (VS Code is used in this tutorial)
- Basic understanding of Javascript ES6
- Nodejs installed, you can get the latest version  [here.](https://nodejs.org/en/download/) 

## Introduction
Working with data from other resources has brought the need to deal with asynchronous operations, that is, operations that do not run in sequence. In this post, I explain, in simple terms one of the ways of handling asynchronous operations in Javascript, **Promises**. By the end of this post, you would understand Javascript Promises in code and simple English.


## What are Javascript Promises?
According to the official documentation:

> The Promise object represents the eventual completion (or failure) of an asynchronous operation and its resulting value.

***SYNTAX:***
``` js
new Promise((resolve, reject)=>{})
```
In simpler terms, a Promise is an object that will return a particular value depending on the state of the Promise. A Promise can have one of three states

- `fulfilled`
- `rejected`
- `pending`

#### Promise `fulfilled`
A promise has a state of `fulfilled`when it is resolved, meaning, nothing went wrong in the Promise and there are no errors. The code snippet below will return a state of fulfilled, because the Promise was resolved:
```js
new Promise((resolve, reject)=>{
    resolve(console.log("Hello"))
})

RESULT:
"Hello"
[[PromiseState]]: "fulfilled"
[[PromiseResult]]: undefined
```

#### Promise `rejected`
A promise has a state of `rejected` when an error occurs. In this case, the Promise was rejected. The code snippet below will return a state of rejected because the Promise was rejected:
```js
new Promise((resolve, reject)=>{
    reject(console.log("Oh no, an error"))
})

RESULT:
"Oh no, an error"
[[PromiseState]]: "rejected"
[[PromiseResult]]: undefined
```

#### Promise `pending`
A promise has a state of `pending` when the Promise itself is neither resolved or rejected. The code snippet below will return a status of `pending` because the Promise is neither resolved nor rejected:
```js
new Promise((resolve, reject)=>{})

RESULT:
[[PromiseState]]: "pending"
[[PromiseResult]]: undefined
```

### Working with Promises
When working with Promises, you might encounter some methods and functions like the ones below

- The `then` method: This method takes the returned values from a resolved Promise and performs some action on them. The `then` method is usually chained to the Promise. See an example below:

``` 
function getDataFromDatabase(){
    return new Promise((resolve, reject)=>{
        // promise resolves with no errors
    })
}

getDataFromDatabase().then((data)=>{
    // data is the returned value from the getFromDatabase function
    console.log(data)
})
```
When working with the `then` keyword, it would be helpful to think of it in plain English like this:

`First of all, get data from the database with the getDataFromDatabase() function, and then console.log all the data gotten from the database`

- The `trycatch` handler: The trycatch handler is very commonly used in working with Promises. Since there is a possibility of your Promise having a `rejected` status, it would be helpful to add a way to catch that error, which is exactly how the trycatch handler works. See an example below: 

```  
function getDataFromDatabase(){
    return new Promise((resolve, reject)=>{
       try {
           // if Promise resolves, return data from the resolve method
           resolve()
       } catch (error) {
           // if the promise rejects, return error data from the reject method
           reject(console.log(error.message))
       }
    })
}

getDataFromDatabase().then((data)=>{
    // data is the returned value from the getFromDatabase function
    console.log(data)
})
```
When working with the `trycatch` handler, it would be helpful to imagine it in plain English like this

`In getting data from the database with the getDataFromDatabase() function, try this code inside this block first, if I successfully get the data, return data from the resolve() function. If I run into some error, return data from the reject function. Then run the function inside the THEN method`

## Code Example
In this example, we are going to try and simulate making an API call to an external endpoint. The idea is to mimic the delay in getting the data when making an API call. Here are the steps we will want to take into account:

1. Create a data store
2. Create a function to get the data (imagine the fetch function in Javascript)
3. Add new data to the data store when we finally get it
4. Log the results to the console

### STEP 1: Create a data store
In this example, we will use a simple array to store items, we are mimicing the database here.
```js
let names = ['Kim Seon Ho', 'Park Seo Joon', 'Park Shin Hye', 'Shin Hye Sun']
```

### STEP 2: Create a function to get the data
Here, we will mimic the delay when getting data from a database with the setTimeout() function. This is where we will use a Promise since we want it to run as an asynchronous function in our theoretical project.
```js
function getData(dataItems) {
    return new Promise((resolve, reject) => {
        try {
            setTimeout(() => {
                resolve(dataItems)
            }, 3000);
        }
        catch (error) {
            reject(console.log(error))
        }
    })
}
```
**WHAT IS HAPPENING: **In this snippet of code, we are making sure the `getData()` function returns a Promise, so we can use the chaining method that Promises provide to change/edit the data when we get it back from the data store.

### STEP 3: Transform the data when we get it
```js
getData(names).then(data=>{
    let newName = 'Han Yoo Joo'
    data.push(newName)
    return data
}).then(finalData=>{
    console.log(finalData)
})
```
**WHAT IS HAPPENING: ** Here, we are getting data using the `getData()` function. The `getData()` function returns information which we store inside the `data` parameter of the `then` method. 
Remember, the `then` method takes returned data from the resolved method in a Promise and is able to perform tasks on it. It is this `data` that we then push a new name into using the `Array.push()` method.

### STEP 4: Log the results to the console
The last `then` method is unnecessary because we can add the `console.log()` method to the first `then` method, however, I added it to show you how much chaining you can use when working with Promises in Javascript. In the last `then`method, we take data returned from the first `then` method and log it to the console.

### RESULTS
```js
[
  'Kim Seon Ho',
  'Park Seo Joon',
  'Park Shin Hye',
  'Shin Hye Sun',
  'Han Yoo Joo'
]
```

## Conclusion
Javascript Promises are a good way of performing asynchronous functions in your code. It is a way better option than facing every Javascript programmers nightmare, callback hell. 
You can find the full code examples in this Github repository:  [**code examples**](https://github.com/Vanneka/asynchronous-javascript-examples) 

Thanks for reading, see you. <br>
Ciao!<br>
Vanessa O.<br>

<hr>
❤ If you found this post useful, remember to share and help me grow my community. ❤

***PS:*** If you're looking to start on your tech career this year, you can download  [this checklist of 14 careers](https://t.co/QhrUnNLVY0?amp=1)  in tech and see the programming language you should learn first.