Jamie Balfour

Welcome to my personal website.

Find out more about me, my personal projects, reviews, courses and much more here.

Part 6.7Promises in JavaScript

Promises were introduced as part of ECMAScript 2015 (ES6) and provide a cleaner way of working with asynchronous operations.

Modern JavaScript applications frequently need to perform actions that take time to complete, such as downloading data from a server, loading files or communicating with APIs.

Promises provide a structured way to handle these operations and are heavily used throughout modern JavaScript, Node.js and React applications.

What promises are

A Promise represents a value that may not be available immediately.

Instead of returning a result instantly, a Promise acts as a placeholder for a future value.

Consider ordering food in a restaurant. The order is placed immediately, but the meal takes time to prepare. A Promise works in a similar way.

Why promises are useful

Before Promises, asynchronous code was often handled using nested callbacks.

JavaScript
loadUser(function(user){
    loadOrders(user, function(orders){
        loadProducts(orders, function(products){
            console.log(products);
        });
    });
});

Deeply nested callbacks can become difficult to read and maintain.

Promises help organise asynchronous code and reduce excessive nesting.

Promise states

Every Promise exists in one of three states:

  • Pending - The operation is still running.
  • Fulfilled - The operation completed successfully.
  • Rejected - The operation failed.

A Promise begins in the pending state and then becomes fulfilled or rejected.

Creating promises

A Promise can be created using the Promise constructor.

JavaScript
const promise = new Promise(
    (resolve, reject) => {

    }
);

The constructor receives two callback functions named resolve and reject.

Resolving promises

Calling resolve() indicates that the operation completed successfully.

JavaScript
const promise = new Promise(
    (resolve, reject) => {
        resolve("Success");
    }
);

Once resolved, the Promise enters the fulfilled state.

Rejecting promises

Calling reject() indicates that an error has occurred.

JavaScript
const promise = new Promise(
    (resolve, reject) => {
        reject("An error occurred");
    }
);

Once rejected, the Promise enters the rejected state.

Using then()

The then() method executes code after a Promise has been fulfilled.

JavaScript
promise.then(
    result => {
        console.log(result);
    }
);

The resolved value becomes available inside the callback function.

Using catch()

The catch() method handles rejected Promises.

JavaScript
promise.catch(
    error => {
        console.error(error);
    }
);

This allows errors to be handled separately from successful results.

Using finally()

The finally() method executes regardless of whether a Promise succeeds or fails.

JavaScript
promise.finally(
    () => {
        console.log("Finished");
    }
);

This is commonly used for cleanup operations.

Chaining promises

Multiple then() calls can be chained together.

JavaScript
promise
    .then(result => {
        return result.toUpperCase();
    })
    .then(result => {
        console.log(result);
    });

Each stage receives the value returned by the previous stage.

Promises and fetch()

One of the most common uses of Promises is the fetch() function.

JavaScript
fetch("/users.json")
    .then(response => {
        return response.json();
    })
    .then(users => {
        console.log(users);
    });

The fetch() function returns a Promise because downloading data can take time.

Promises in React

Promises are commonly used within React applications when loading data from APIs.

JavaScript
fetch("/api/users")
    .then(response => {
        return response.json();
    })
    .then(users => {
        console.log(users);
    });

Although modern React applications often use async and await, these features are built on top of Promises.

Understanding Promises makes it easier to understand asynchronous programming in React.

When to use promises

Promises should be used whenever an operation completes asynchronously.

Common examples include loading data from servers, reading files and communicating with APIs.

Since Promises are the foundation of modern asynchronous JavaScript, they should be understood before moving on to async and await.

Feedback 👍
Comments are sent via email to me.