DEV Community

Cover image for JavaScript Promises: Best Practices & Keeping Your Code Clean
Harish Kumar
Harish Kumar

Posted on • Updated on

JavaScript Promises: Best Practices & Keeping Your Code Clean

A JavaScript Promise is an object that represents the eventual completion (or failure) of an asynchronous operation and its resulting value. Promises provide a cleaner and more intuitive way to work with asynchronous code compared to traditional callback-based approaches.

👉 Download eBook - JavaScript: from ES2015 to ES2023

.

Key Concepts

  1. States: A Promise has three states:

    • Pending: The initial state, neither fulfilled nor rejected.
    • Fulfilled: The operation was completed successfully.
    • Rejected: The operation failed.
  2. Creating a Promise:

   const myPromise = new Promise((resolve, reject) => {
     // Asynchronous operation
     if (/* operation successful */) {
       resolve('Success!');
     } else {
       reject('Error!');
     }
   });
Enter fullscreen mode Exit fullscreen mode
  1. Using Promises:
    • then: Attaches callbacks for the fulfilled case and the rejected case.
    • catch: Attaches a callback for the rejected case.
    • finally: Attaches a callback that is executed regardless of the promise's outcome.
   myPromise
     .then((value) => {
       console.log(value); // "Success!"
     })
     .catch((error) => {
       console.error(error); // "Error!"
     })
     .finally(() => {
       console.log('Operation completed');
     });
Enter fullscreen mode Exit fullscreen mode

Promises in Action

Basic Example

Here's a simple example of using a Promise to simulate an asynchronous operation:

const fetchData = () => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      const success = true; // Simulate success or failure
      if (success) {
        resolve('Data fetched successfully!');
      } else {
        reject('Failed to fetch data.');
      }
    }, 2000);
  });
};

fetchData()
  .then((message) => console.log(message))
  .catch((error) => console.error(error));
Enter fullscreen mode Exit fullscreen mode

Chaining Promises

Promises can be chained to handle a sequence of asynchronous operations:

const step1 = () => Promise.resolve('Step 1 complete');
const step2 = () => Promise.resolve('Step 2 complete');
const step3 = () => Promise.resolve('Step 3 complete');

step1()
  .then((result1) => {
    console.log(result1);
    return step2();
  })
  .then((result2) => {
    console.log(result2);
    return step3();
  })
  .then((result3) => {
    console.log(result3);
  })
  .catch((error) => {
    console.error(error);
  });
Enter fullscreen mode Exit fullscreen mode

Advanced Usage

Promise.all

Executes multiple promises in parallel and waits for all of them to be resolved or any of them to be rejected:

const promise1 = Promise.resolve('Promise 1 resolved');
const promise2 = Promise.resolve('Promise 2 resolved');
const promise3 = Promise.resolve('Promise 3 resolved');

Promise.all([promise1, promise2, promise3])
  .then((values) => {
    console.log(values); // ['Promise 1 resolved', 'Promise 2 resolved', 'Promise 3 resolved']
  })
  .catch((error) => {
    console.error(error);
  });
Enter fullscreen mode Exit fullscreen mode

Promise.race

Waits for the first promise to be settled (resolved or rejected):

const promise1 = new Promise((resolve) => setTimeout(resolve, 500, 'First'));
const promise2 = new Promise((resolve) => setTimeout(resolve, 100, 'Second'));

Promise.race([promise1, promise2])
  .then((value) => {
    console.log(value); // 'Second'
  })
  .catch((error) => {
    console.error(error);
  });
Enter fullscreen mode Exit fullscreen mode

Conclusion

JavaScript Promises offer a powerful way to handle asynchronous operations, making the code more readable and maintainable. By understanding and utilizing Promises effectively, developers can write cleaner and more efficient asynchronous code.

👉 Download eBook - JavaScript: from ES2015 to ES2023
javascript-from-es2015-to-es2023

Top comments (0)