Promises Made Easy: A Beginner's Guide to Javascript Promises

A promise is like a special box that can hold something that we might get in the future. For example, imagine you order a pizza and the delivery person promises to bring it to your door. You can't eat the pizza yet, but you know it's coming soon.

In JavaScript, promises work in a similar way. When you make a request to a server or ask for some data, you might not get an immediate response. Instead, you can create a promise that represents the response you expect to receive in the future.

Promises have two important states: "pending" and "settled". When a promise is pending, it means that we're still waiting for the response. Once the response arrives, the promise becomes "settled" and can be either "fulfilled" if everything went well, or "rejected" if there was an error.

When you create a promise, you can attach "callbacks" that will be called when the promise is fulfilled or rejected. These callbacks are like instructions for what to do with the response when it finally arrives.

Here's an example of how you might use a promise in JavaScript:

const fetchData = () => {
  return new Promise((resolve, reject) => {
    fetch('https://example.com/data')
      .then(response => {
        if (!response.ok) {
          throw new Error('Network response was not ok');
        }
        return response.json();
      })
      .then(data => resolve(data))
      .catch(error => reject(error));
  });
};

fetchData()
  .then(data => console.log(data))
  .catch(error => console.error(error));

Let's break down this code and see what it's doing:

  1. First, we define a function called fetchData. This function creates a new promise by calling the Promise constructor and passing in a function with two parameters: resolve and reject.

  2. Inside the promise function, we use the fetch function to make a network request to an endpoint that returns some JSON data. We chain a few then methods to the promise to handle the response:

    • If the response is not okay (i.e., the server returned an error), we throw an error.

    • If the response is okay, we parse the JSON data and pass it to the resolve function, which sets the promise state to "fulfilled".

  3. If there's an error at any point in the promise chain (e.g., a network error), we catch the error and pass it to the reject function which sets the promise state to "rejected".

  4. Finally, we call the fetchData function and attach two callbacks to the promise using the then and catch methods:

    • If the promise is fulfilled, we log the data to the console.

    • If the promise is rejected, we log the error to the console.

we can also refactor this code by using async/await

const fetchData = async () => {
  const response = await fetch('https://example.com/data');
  if (!response.ok) {
    throw new Error('Network response was not ok');
  }
  const data = await response.json();
  return data;
};

fetchData()
  .then(data => console.log(data))
  .catch(error => console.error(error));

Let's see what's changed:

  1. We've changed the fetchData function to use the async/await syntax instead of creating a new promise. This allows us to write asynchronous code that looks more like synchronous code.

  2. We use await to wait for the network request to complete, and then check if the response is okay. If it's not okay, we throw an error.

  3. If the response is okay, we parse the JSON data using await and return the data.

  4. In the main program, we call the fetchData function and attach the same then and catch callbacks as before.

So in short, promises are a way to handle asynchronous actions in JavaScript, and they allow you to write code that can wait for a response without blocking other parts of your program

Did you find this article valuable?

Support Insightful Bytes by becoming a sponsor. Any amount is appreciated!