DEV Community

Bogdan Varlamov
Bogdan Varlamov

Posted on

Enhancing JavaScript with Promise.withResolvers()

Image description

Since March 2024, Promise.withResolvers() has been supported across the latest devices and browsers. This feature introduces a static method that returns an object containing a new Promise and two functions to either resolve or reject it.



const { promise, resolve, reject } = Promise.withResolvers()


Enter fullscreen mode Exit fullscreen mode

This method provides an alternative to the traditional new Promise() constructor. It is especially useful in scenarios where the logic to resolve or reject the promise doesn't fit neatly into a single function.

Simple Example

Imagine you want to create a promise that resolves when a user clicks a button. Typically, you might set up an event listener inside a promise executor. However, with Promise.withResolvers(), you can streamline the process:



<button id="myButton">Click Me!</button>
<script>
    const { promise, resolve, reject } = Promise.withResolvers();

    document.getElementById("myButton").addEventListener('click', () => {
        resolve("Button clicked!");
    });

    promise.then(alert).catch(console.error);
</script>


Enter fullscreen mode Exit fullscreen mode

In contrast, here's how you might handle it with a standard Promise constructor:



<button id="myButton">Click Me!</button>
<script>
    function waitForButtonClick() {
        return new Promise((resolve, reject) => {
            document.getElementById("myButton").addEventListener('click', () => {
                resolve("Button clicked!");
            });
        });
    }

    waitForButtonClick().then(alert).catch(console.error);
</script>


Enter fullscreen mode Exit fullscreen mode

Comparing Approaches

  • Encapsulation: The traditional approach encapsulates the promise creation and event handling logic within a single function. This can be restrictive if multiple conditions or different parts of your code need to resolve or reject the promise.
  • Flexibility: Promise.withResolvers() offers greater flexibility by separating the creation of the promise from the resolution logic, which is ideal for managing complex conditions or multiple events.
  • Code Management: For straightforward use cases, the traditional method may be simpler, particularly for those familiar with standard promise patterns.

Good case to use Promise.withResolvers()

Promise.withResolvers() shines in scenarios like game development or interactive applications where outcomes are influenced by multiple, unpredictable events. For example, in a game, actions such as "win," "lose," or "timeout" might determine the next steps.

Why Promise.withResolvers() is Optimal:

  • Decoupling Event Handling: It allows separate definition of resolution mechanisms from the event monitoring, improving code organization and management of complex conditions.
  • Reusable Logic: The resolve and reject functions can be reused across different game scenarios, enabling flexible handling of various outcomes like winning, losing, or pausing.
  • Simplified State Management: It makes managing asynchronous state transitions cleaner by separating the transitions from the handling logic.

Example



<button id="winButton">Win</button>
<button id="loseButton">Lose</button>
<button id="timeoutButton">Timeout</button>
<script>
    const { promise, resolve, reject } = Promise.withResolvers();

    document.getElementById("winButton").addEventListener('click', () => resolve("Win"));
    document.getElementById("loseButton").addEventListener('click', () => resolve("Lose"));
    document.getElementById("timeoutButton").addEventListener('click', () => reject("Timeout"));

    promise.then(result => {
        console.log("Game Over: " + result);
    }).catch(error => {
        console.log("Game Over: " + error);
    });
</script>


Enter fullscreen mode Exit fullscreen mode

This example illustrates how Promise.withResolvers() effectively manages multiple potential outcomes in an interactive setting, cleanly separating the game logic from the event handling.

Thanks for hanging out! Hit subscribe for more! 👋

Top comments (3)

Collapse
 
rakchamp profile image
Ajith kannan • Edited

Awesome. Learned something new today

Collapse
 
melroy89 profile image
Melroy van den Berg

This feels kinda weird it's like a global promise.. This can be very unpredictable when used cross a large code base.. The result in promise.then could be of any type..

Collapse
 
crazytanukifoxmailcom_4 profile image
crazytanuki@foxmail.com

Can it be used for multiple asynchronous functions?