Asynchronous JavaScript

Understanding Promises in JavaScript

high-level programming language

High-level programming language.

Promises in JavaScript represent a significant leap forward in how we handle asynchronous operations. They provide a more powerful and flexible way of dealing with operations that may take an unknown amount of time to complete, such as fetching data from a server.

What is a Promise?

A Promise in JavaScript is an object that represents the eventual completion or failure of an asynchronous operation. It serves as a placeholder for the eventual results of the operation.

A Promise is always in one of three states:

  • Pending: The Promise's outcome hasn't yet been determined, because the asynchronous operation that will produce its result hasn't completed yet.
  • Fulfilled: The asynchronous operation has completed, and the Promise has a resulting value.
  • Rejected: The asynchronous operation failed, and the Promise will never be fulfilled. In the rejected state, a Promise has a reason that indicates why the operation failed.

Creating and Returning Promises

A Promise is created using the Promise constructor, which takes a single argument: a callback function known as the executor. The executor function takes two parameters: resolve and reject, which are functions that change the state of the Promise.

Here's an example of creating a Promise:

let promise = new Promise((resolve, reject) => { // Asynchronous operation goes here });

The resolve function is used to change the state of the Promise to fulfilled and set its result value. The reject function is used to change the state of the Promise to rejected and set its reason.

Promise Methods: .then(), .catch(), and .finally()

Promises provide several methods that you can use to attach callbacks that will be invoked when the Promise is settled.

  • .then(): This method returns a Promise and takes up to two arguments: callback functions for the success and failure cases respectively.
promise.then(value => { // Success case }, reason => { // Failure case });
  • .catch(): This method is a shorthand for .then(null, rejection), and it's used to specify a callback to be executed when the Promise is rejected.
promise.catch(reason => { // Failure case });
  • .finally(): This method allows you to specify a callback that will be executed when the Promise is settled, regardless of its outcome. It's often used for cleanup tasks.
promise.finally(() => { // Code to run after the Promise is settled });

Chaining Promises

One of the key features of Promises is the ability to chain them together. This means that you can create a sequence of asynchronous operations that are executed one after the other. Each .then() returns a new Promise, allowing you to chain them.

doSomething() .then(result => doSomethingElse(result)) .then(newResult => doThirdThing(newResult)) .catch(failureCallback);

In this example, doSomethingElse will not be started until doSomething has completed, and similarly, doThirdThing will not be started until doSomethingElse has completed.

By the end of this unit, you should have a solid understanding of how to create, return, and chain Promises in JavaScript, and how to handle their success or failure cases.