Skip to main content

Mastering The Promises in JavaScript

mastering-the-promises-in-javascript

Promises are a powerful feature in JavaScript that allow you to handle asynchronous operations and manage the flow of asynchronous code execution. A promise represents the eventual completion or failure of an asynchronous operation and allows you to handle the result or error in a more structured and elegant way.

Promises have three states:

  1. Pending: The initial state. The promise is still in progress and has not been fulfilled or rejected yet.
  2. Fulfilled: The promise is successfully fulfilled with a result value.
  3. Rejected: The promise encounters an error or is rejected with a reason.

Example:

const myPromise = new Promise((resolve, reject) => {
  // Asynchronous operation
  setTimeout(() => {
    const randomNumber = Math.random();
    if (randomNumber > 0.5) {
      resolve(randomNumber); // Fulfill the promise with the random number
    } else {
      reject(new Error("Random number is too small!")); // Reject the promise with an error
    }
  }, 2000);
});

myPromise
  .then(result => {
    console.log("Promise fulfilled with result:", result);
  })
  .catch(error => {
    console.log("Promise rejected with error:", error);
  });

In this example, we create a promise using the Promise constructor, which takes a callback function with two parameters: resolve and reject. Inside the callback function, we perform an asynchronous operation using setTimeout. If the random number generated is greater than 0.5, we call resolve and pass the random number as the fulfillment value. Otherwise, we call reject and pass an Error object as the reason for rejection.

We then chain the then and catch methods on the promise. The then method is called when the promise is fulfilled, and it receives the fulfillment value as an argument. The catch method is called when the promise is rejected, and it receives the rejection reason as an argument.

Promises provide a more structured and readable way to handle asynchronous operations and their results. They allow you to avoid callback hell and handle errors in a centralized manner using the catch method. Additionally, promises can be chained together using multiple then calls, enabling sequential execution and transformation of asynchronous results.


Example 1: Handling AJAX Requests"

function makeRequest(url) {
  return new Promise((resolve, reject) => {
    const xhr = new XMLHttpRequest();
    xhr.open('GET', url);
    xhr.onload = () => {
      if (xhr.status === 200) {
        resolve(xhr.responseText);
      } else {
        reject(new Error(xhr.statusText));
      }
    };
    xhr.onerror = () => {
      reject(new Error('Network error'));
    };
    xhr.send();
  });
}

makeRequest('https://api.example.com/data')
  .then(response => {
    console.log('Request successful:', response);
  })
  .catch(error => {
    console.log('Request failed:', error);
  });

In this example, a promise is created to handle an AJAX request. If the request is successful, the promise is fulfilled with the response text. If there's an error or the request fails, the promise is rejected with an appropriate error message.


Example 2: "Chaining Promises"

function asyncOperation() {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve('First result');
    }, 1000);
  });
}

asyncOperation()
  .then(result => {
    console.log('First operation:', result);
    return 'Second result';
  })
  .then(result => {
    console.log('Second operation:', result);
    throw new Error('Something went wrong');
  })
  .catch(error => {
    console.log('Error:', error.message);
  });

In this example, we have an asynchronous operation represented by the asyncOperation function. We chain multiple then calls to perform sequential operations. Each then call receives the result of the previous operation and returns a new value or performs another asynchronous operation. If any error occurs, it is caught by the catch method.


Example 3: "Promise.all"

const promise1 = Promise.resolve('Hello');
const promise2 = new Promise((resolve, reject) => {
  setTimeout(() => resolve('World'), 2000);
});
const promise3 = fetch('https://api.example.com/data');

Promise.all([promise1, promise2, promise3])
  .then(results => {
    console.log('All promises resolved:', results);
  })
  .catch(error => {
    console.log('Error:', error);
  });

In this example, we use Promise.all to handle multiple promises simultaneously. It takes an array of promises and returns a new promise that fulfills when all the input promises are fulfilled, or rejects if any of the input promises are rejected. The results array in the then block contains the fulfillment values of all the input promises.

These examples illustrate different aspects of promises, such as handling AJAX requests, chaining promises for sequential operations, and using Promise.all for parallel processing. Promises provide a flexible and efficient way to work with asynchronous operations in JavaScript, improving code readability and maintainability.


Read Also:

 

Comments