Unlock the Power of JavaScript Promises
Declarative Programming: A New Approach
Traditional imperative programming focuses on specifying how to achieve a task. Declarative programming, on the other hand, focuses on what needs to happen. This shift in perspective can lead to more concise and readable code. With promises, you can write code that declares the intent, making it easier to understand and maintain.
The Benefits of Promises
Promises contribute to better code by allowing you to write more declarative, concise, and readable code. They help you visualize the steps your data goes through, making it easier to understand and debug. By using promises, you can avoid callback hell and write more robust, asynchronous code.
Handling Multiple Promises
When working with multiple promises, you need a way to handle them efficiently. Promise.all()
is a great method for this, as it returns a promise that resolves when all the passed promises have been resolved. However, it has a limitation: if one promise fails, the entire process is halted.
const promise1 = new Promise((resolve, reject) => {
// some operation
resolve("promise 1 resolved");
});
const promise2 = new Promise((resolve, reject) => {
// some operation
resolve("promise 2 resolved");
});
Promise.all([promise1, promise2]).then((values) => {
console.log(values); // ["promise 1 resolved", "promise 2 resolved"]
});
Solving Partial Failures with Promise.allSettled()
Promise.allSettled()
is a solution to partial failures. It returns a list of values, each with a status (fulfilled or rejected) and a value or reason. This method allows you to execute all promises, ignoring possible rejections along the way.
const promise1 = new Promise((resolve, reject) => {
// some operation
resolve("promise 1 resolved");
});
const promise2 = new Promise((resolve, reject) => {
// some operation
reject("promise 2 rejected");
});
Promise.allSettled([promise1, promise2]).then((values) => {
console.log(values);
// [
// { status: "fulfilled", value: "promise 1 resolved" },
// { status: "rejected", reason: "promise 2 rejected" }
// ]
});
Using Promise.race()
Promise.race()
is another way to work with multiple promises. It returns a promise that fulfills or rejects as soon as one of the promises in the array is fulfilled or rejected. This method is useful when you want to take the result from the first promise that settles.
const promise1 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("promise 1 resolved");
}, 2000);
});
const promise2 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("promise 2 resolved");
}, 1000);
});
Promise.race([promise1, promise2]).then((value) => {
console.log(value); // "promise 2 resolved"
});
Real-World Use Cases
Promise.race()
has several real-world use cases, such as:
- Performance checks: Use
Promise.race()
to query multiple data sources and return the fastest result. - Determining when to display a loading indicator: Use
Promise.race()
to decide whether to show a loading indicator based on the response time of an asynchronous request.
Responding to Rejected Promises
Promise.prototype.catch()
is a handy method for responding to rejected promises. It returns a promise that is rejected if the onRejected function throws an error or returns a rejected promise. This method can be chained, allowing you to catch multiple errors.
const promise = new Promise((resolve, reject) => {
reject("promise rejected");
});
promise.catch((reason) => {
console.log(reason); // "promise rejected"
});