Promises in Javascript Explained + Examples

Promises in Javascript Explained + Examples

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.

Introduction

Working with data from other resources has brought the need to deal with asynchronous operations, ie 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:

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 fulfilledwhen 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:

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:

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:

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.

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.

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

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 thenmethod, we take data returned from the first then method and log it to the console.

RESULTS

[
  '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

Thanks for reading, see you.
Ciao!
Vanessa O.


❤ 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 in tech and see the programming language you should learn first.