DEV Community

Cover image for How Promises works in Javascript? - An Overview
Nishanthan K
Nishanthan K

Posted on

How Promises works in Javascript? - An Overview

Promise

  • In real-world applications we have to invoke/call one function with the result of another function, simply one function is dependent on another function's result.
  • But we don’t know when the 1st function will complete so that we can call the 2nd function also even we didn’t know if the 1st function got stuck with some errors.
  • We can overcome this with the help of nested callback with nested try/catch but it will lead to callback hell.
  • Problem 1 - Don’t know whether the function execution was completed or not
  • Problem 2 - Don’t know whether the function executed without errors or not
  • Problem 3 - Code will look very messy and unstructured
  • On the other hand, Promise also will be doing the same thing but in a more structured way and making the code more readable and easily accessible.

Promise overview

  • A promise is an object that contains a status (promiseStatus) and value (promiseValue).

Promise Status

  • Promise has three status

• ✅ fulfilled: The promise has been resolved. Everything went fine, no errors occurred within the promise 🥳

• ❌ rejected: The promise has been rejected. Or something went wrong…

• ⏳ pending: The promise has neither been resolved nor rejected (yet), the promise is still pending.

Promise Value

  • The value of a promise, the value of [[PromiseValue]], is the value that we pass to either the resolved or rejected method as their argument.

Example 1

function uploadDocument() {
    return new Promise((resolve) => {
            console.log("Document uploaded");
            resolve("document.docx");
    });
}

function convertToPDF(filename) {
    return new Promise((resolve) => {
            console.log(`Converted ${filename} to PDF`);
            resolve("document.pdf");
    });
}

function extractData(pdfFile) {
    return new Promise((resolve) => {
            console.log(`Extracted data from ${pdfFile}`);
            resolve("Extracted content");
    });
}

uploadDocument()
    .then((filename) => {
        return convertToPDF(filename).then((pdfFile) => {
            return extractText(pdfFile).then((result) => {
                console.log(result);
            });
        });
    })
    .catch((error) => console.error("Error:", error));

Enter fullscreen mode Exit fullscreen mode
  • .then(): Gets called after a promise is resolved.
  • .catch(): Gets called after a promise is rejected.
  • We can still simplify this with the help of Async/Await.

Async/Await

  • In the above example, we are using the Promise constructor to create a Promise but in ES7, Async/Await was introduced which will return the result in Promise format by default.
  • Async/Await both are only applicable to functions and the await keyword is only to be used if the function is async.
  • So we don’t need to write new Promise(() => {})Promise.resolve, or Promise.reject all the time.

Example 2

async function processDocument() {
    try {
        const filename = await uploadDocument();
        const pdfFile = await convertToPDF(filename);
        const result = await extractData(pdfFile);
        console.log(result);
    } catch (error) {
        console.error("Error:", error);
    }
}

processDocument();

Enter fullscreen mode Exit fullscreen mode

Key Differences

  • Promise Chaining:
    • The .then() structure results in nested calls, which can become difficult to manage in larger workflows.
  • async / await:
    • Makes the code more linear and easier to read while maintaining the same functionality.

Other methods in Promise

Promise.all

  • Waits for all promises in an array to resolve or any one of them to reject.
  • Returns a single promise that resolves with an array of results when all input promises are resolved.
  • If any promise rejects, the entire Promise.all rejects.
const promise1 = Promise.resolve(10);
const promise2 = Promise.resolve(20);

Promise.all([promise1, promise2])
    .then((results) => console.log(results)) // Output: [10, 20]
    .catch((error) => console.error(error));

Enter fullscreen mode Exit fullscreen mode

Promise.allSettled

  • Waits for all promises to either resolve or reject.
  • Returns an array of results containing the status and value/reason of each promise.
const promise1 = Promise.resolve(10);
const promise2 = Promise.reject("Error!");

Promise.allSettled([promise1, promise2])
    .then((results) => console.log(results));
/* Output:
[
  { status: 'fulfilled', value: 10 },
  { status: 'rejected', reason: 'Error!' }
]
*/

Enter fullscreen mode Exit fullscreen mode

Promise.race

  • Resolves or rejects as soon as the first promise in the array settles (resolves or rejects).
  • The returned promise adopts the state (fulfilled or rejected) of the first promise to settle.
const promise1 = new Promise((resolve) => setTimeout(resolve, 100, "First"));
const promise2 = new Promise((resolve) => setTimeout(resolve, 50, "Second"));

Promise.race([promise1, promise2])
    .then((result) => console.log(result)) // Output: Second
    .catch((error) => console.error(error));

Enter fullscreen mode Exit fullscreen mode

Promise.any

  • Resolves as soon as the first promise resolves.
  • If all promises reject, it rejects with an AggregateError containing all rejection reasons.
const promise1 = Promise.reject("Error 1");
const promise2 = Promise.resolve("Success!");
const promise3 = Promise.reject("Error 2");

Promise.any([promise1, promise2, promise3])
    .then((result) => console.log(result)) // Output: Success!
    .catch((error) => console.error(error)); // Only if all promises reject

Enter fullscreen mode Exit fullscreen mode

Promise.resolve

  • Returns a promise that resolves with the given value.
  • If the value is a promise, it returns that promise.
Promise.resolve("Hello")
    .then((result) => console.log(result)); // Output: Hello

Enter fullscreen mode Exit fullscreen mode

Promise.reject

  • Returns a promise that is immediately rejected with the specified reason.
Promise.reject("Error occurred")
    .catch((error) => console.error(error)); // Output: Error occurred

Enter fullscreen mode Exit fullscreen mode

Note

Promise Chaining isn't a built-in type but involves chaining .then() calls for sequential asynchronous operations.

Promise.resolve(10)
    .then((result) => result * 2)
    .then((result) => result + 5)
    .then((result) => console.log(result)); // Output: 25

Enter fullscreen mode Exit fullscreen mode
Method Description
Promise.all Resolves when all promises resolve, rejects if any promise rejects.
Promise.allSettled Resolves when all promises settle (fulfilled or rejected).
Promise.race Resolves/rejects as soon as the first promise settles.
Promise.any Resolves as soon as the first promise resolves, rejects if all reject.
Promise.resolve Returns a resolved promise.
Promise.reject Returns a rejected promise.

Top comments (0)