23 Feb 2024




Intermediate

Promises represent the eventual success or failure of an asynchronous operation, allowing handling of results or errors after the operation finishes. Promises have states (pending, fulfilled, or rejected) and provide methods like then() and catch() for handling successful results or errors, respectively.

Promises are commonly used for handling asynchronous operations such as fetching data from a server, reading files, or executing animations.

A promise can be in one of three states:

  1. Pending: Initial state, neither fulfilled nor rejected.
  2. Fulfilled: The operation completed successfully.
  3. Rejected: The operation failed.

The syntax for creating a promise is:

const myPromise = new Promise((resolve, reject) => {
  // Perform an asynchronous operation, such as fetching data or reading a file
  
  // If the operation is successful, call resolve with the result
  // resolve(result);
  
  // If the operation fails, call reject with an error
  // reject(error);
});

Concise overview of the parameters:

  • resolve: Function to call when the asynchronous operation is successful. It accepts a value (or undefined) indicating the fulfillment of the promise.
  • reject: Function to call when the asynchronous operation fails. It accepts an error object as an argument.

You can then use promise methods such as .then() and .catch() to handle the fulfillment and rejection of the promise respectively:

myPromise.then((result) => {
  // Handle the successful fulfillment of the promise
}).catch((error) => {
  // Handle the rejection of the promise
});

Promises also support chaining, which allows you to execute asynchronous operations sequentially:

myPromise
  .then((result) => {
    // First asynchronous operation completed successfully
    // Perform another asynchronous operation and return a new promise
    return anotherAsyncOperation(result);
  })
  .then((anotherResult) => {
    // Handle the result of the second asynchronous operation
  })
  .catch((error) => {
    // Handle any errors that occurred during the chain of asynchronous operations
  });

Promises provide a cleaner alternative to using nested callbacks, making asynchronous code easier to read and maintain. They are an integral part of modern JavaScript programming, especially in handling asynchronous operations in a more synchronous-looking manner.

Example :

Fetch user data from a hypothetical API endpoint using the fetch API, which returns a promise itself. Here's how you can do it:

function getUserData() {
    return new Promise((resolve, reject) => {
        fetch('https://api.example.com/user')
            .then(response => {
                if (!response.ok) {
                    // If the response is not successful, reject the promise with an error
                    throw new Error('Failed to fetch user data');
                }
                // If the response is successful, parse the JSON response and resolve the promise
                return response.json();
            })
            .then(userData => {
                // Resolve the promise with the user data retrieved from the API
                resolve(userData);
            })
            .catch(error => {
                // If any error occurs during the process, reject the promise with the error
                reject(error);
            });
    });
}

// Usage
getUserData()
    .then(userData => {
        // If the promise is resolved successfully, log the user data
        console.log('User data:', userData);
    })
    .catch(error => {
        // If the promise is rejected with an error, log the error
        console.error('Error fetching user data:', error);
    });

In the above example:

  • The resolve function is used to fulfill the promise with a value, in this case, the user data retrieved from the API.
  • The reject function is used to indicate that the promise has been rejected, typically due to an error encountered during the asynchronous operation.
  • Inside the promise constructor function, resolve is called when the user data is successfully retrieved from the API, and reject is called if any error occurs during the process.
  • The .then() method is used to handle the fulfillment of the promise (i.e., when resolve is called), and the .catch() method is used to handle the rejection of the promise (i.e., when reject is called or when an error occurs during the promise chain).

This example demonstrates the use of resolve and reject functions in a promise to handle asynchronous operations, such as fetching data from an API, and how to handle the fulfillment or rejection of the promise accordingly.

javascript
promises