Contact Us

Email: info@mohitdesigns.com
Mobile: +91-9718991639

javascript promises

Mastering JavaScript Promises: Resolve, Reject, and Then Explained

JavaScript promises have revolutionized the way developers handle asynchronous operations, replacing callback functions with a more intuitive and maintainable approach. Promises provide a mechanism to handle asynchronous tasks that might either succeed or fail and allow you to manage these outcomes in a clean, structured way. In this comprehensive guide, we will cover the basics of JavaScript promises, focusing on key concepts like resolve, reject, then, and Promise.allSettled.

What is a Promise?

A promise in JavaScript is an object representing the eventual completion or failure of an asynchronous operation. When a promise is created, it can be in one of three states:

  • Pending: The operation has not been completed yet.
  • Resolved (Fulfilled): The operation was successful, and the promise has been resolved.
  • Rejected: The operation failed, and the promise has been rejected.

Using promises makes asynchronous code easier to read and manage, as they prevent “callback hell” and simplify error handling.

The resolve Function

The resolve function is called when a promise is successfully fulfilled. It allows you to pass a value to the next step in the promise chain using the then() method.

Example:

let successfulPromise = new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve("Data fetched successfully");
    }, 2000);
});

successfulPromise.then(result => {
    console.log(result); // Output: "Data fetched successfully"
});

In this example, the promise is resolved after a 2-second delay, passing a success message to the then() block.

The reject Function

The reject function is used when an error occurs during the asynchronous operation. It moves the promise to the rejected state and passes the error message or object.

Example:

let failedPromise = new Promise((resolve, reject) => {
    setTimeout(() => {
        reject("Failed to fetch data");
    }, 2000);
});

failedPromise.catch(error => {
    console.error(error); // Output: "Failed to fetch data"
});

Here, the promise is rejected after 2 seconds, and the error is handled by the catch() method.

The then Method

The .then() method allows you to specify what should happen once a promise is resolved. You can chain multiple then() methods to handle the results of several asynchronous operations sequentially.

Example:

let asyncTask = new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve(5);
    }, 1000);
});

asyncTask
    .then(result => {
        console.log(result); // Output: 5
        return result * 2;
    })
    .then(result => {
        console.log(result); // Output: 10
        return result * 3;
    })
    .then(result => {
        console.log(result); // Output: 30
    });

In this case, the result of each promise is passed to the next then() block, forming a chain of asynchronous actions.

Handling Multiple Promises with Promise.all

Sometimes, you may want to execute several asynchronous operations in parallel and wait for all of them to complete before continuing. Promise.all() is designed to do exactly that. It takes an array of promises and resolves once all the promises have successfully resolved. If any of the promises are rejected, Promise.all() will reject immediately.

Example:

let promise1 = new Promise((resolve) => setTimeout(() => resolve("Task 1 complete"), 1000));
let promise2 = new Promise((resolve) => setTimeout(() => resolve("Task 2 complete"), 2000));

Promise.all([promise1, promise2])
    .then(results => {
        console.log(results); // Output: ["Task 1 complete", "Task 2 complete"]
    })
    .catch(error => {
        console.error(error);
    });

Here, Promise.all() waits for both promises to resolve and then logs their results in an array.

Introducing Promise.allSettled

While Promise.all() will reject if any of the promises fail, Promise.allSettled() provides a way to wait for all promises to complete, regardless of whether they are resolved or rejected. It returns an array of objects, each object representing the outcome of each promise.

Example:

let promise1 = new Promise((resolve) => setTimeout(() => resolve("Task 1 complete"), 1000));
let promise2 = new Promise((resolve, reject) => setTimeout(() => reject("Task 2 failed"), 2000));

Promise.allSettled([promise1, promise2])
    .then(results => {
        console.log(results);
        // Output:
        // [
        //   { status: 'fulfilled', value: 'Task 1 complete' },
        //   { status: 'rejected', reason: 'Task 2 failed' }
        // ]
    });

In this example, Promise.allSettled() waits for both promises to complete and returns their results. Even though one of the promises is rejected, it doesn’t prevent the other promise from being fulfilled. This is particularly useful when you need the results of all promises, regardless of individual failures.

Chaining Promises

Promises can be chained using .then(), allowing you to perform multiple asynchronous operations in sequence. Each .then() returns a new promise, which can be further chained.

let promiseChain = new Promise((resolve) => {
    resolve(10);
});

promiseChain
    .then(result => {
        console.log(result); // Output: 10
        return result + 5;
    })
    .then(result => {
        console.log(result); // Output: 15
        return result * 2;
    })
    .then(result => {
        console.log(result); // Output: 30
    });

In this example, the result of each .then() block is passed to the next one, allowing for a sequence of dependent operations.

Error Handling in Promises

One of the major advantages of promises is how they handle errors. If an error occurs at any point in the chain, it will be caught by the nearest catch() method, skipping the remaining .then() blocks.

Example:

let errorHandlingPromise = new Promise((resolve, reject) => {
    reject("Something went wrong!");
});

errorHandlingPromise
    .then(() => {
        console.log("This won't be logged");
    })
    .catch(error => {
        console.error(error); // Output: "Something went wrong!"
    });

In this case, the error is caught immediately, and the error message is logged.

Conclusion: JavaScript Promises

Mastering JavaScript promises is crucial for writing clean and efficient asynchronous code. The resolve, reject, and then functions form the foundation of promise-based programming, allowing developers to manage async operations more easily. Tools like Promise.all() and Promise.allSettled() further simplify working with multiple promises, offering more flexibility in handling both success and failure.

By understanding these core concepts, you can handle asynchronous JavaScript with greater confidence, ensuring that your code is not only functional but also robust and maintainable.