DEV Community

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

Posted on • Edited 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!');
     }
    });
    
  3. 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)