JavaScript Promise.withResolvers

摘要: 在本教程中,您将学习如何使用 JavaScript Promise.withResolvers() 方法来创建一个新的 Promise,其中包含其 resolvereject 函数。

JavaScript Promise.withResolvers 方法简介

创建一个新的 Promise 对象 时,您通常会将 resolvereject 函数传递给 Promise 构造函数,如下所示

const promise = new Promise((resolve, reject) =>{
   // ...
});Code language: JavaScript (javascript)

这允许您仅在 Promise 构造函数内部调用 resolvereject 函数。

要在 Promise 构造函数之外调用这些函数,您通常需要编写以下样板代码

let resolve, reject;

const promise = new Promise((res, rej) => {
    resolve = res;
    reject = rej;
});

Math.random() > 0.5 ? resolve("Success") : reject("Error");Code language: JavaScript (javascript)

在此代码中

  • 首先,声明保存 Promise 的 resolvereject 函数的变量。
  • 其次,使用 Promise 构造函数创建一个新的 Promise 对象,并将 resolvereject 函数分配给这些变量。这使得 resolvereject 函数可以在 Promise 构造函数之外使用。
  • 第三,在 Promise 构造函数之外调用 resolvereject 函数。

使用 Promise.withResolvers() 函数,您可以像这样简化代码

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

Math.random() > 0.5 ? resolve("Success") : reject("Error");Code language: JavaScript (javascript)

在此代码中,Promise.withResolvers() 方法返回一个包含以下属性的对象

  • promise: 一个新的 Promise 对象
  • resolve: 用于解决 Promise 的函数。
  • reject: 用于拒绝 Promise 的函数。

请注意,Promise.withResolvers() 自 ECMAScript 2024 起可用。

JavaScript Promise.withResolvers 方法示例

以下示例演示了如何使用 Promise.withResolvers() 方法来处理用户输入。

假设您有一个 对话框,提示用户批准或拒绝请求。当用户打开对话框时,将显示“批准”和“拒绝”按钮。

如果您不使用 Promise,您可以像这样处理“批准/拒绝”按钮的点击事件

const btnReview = document.querySelector('#btnReview');

btnReject.addEventListener('click', () => {
  // handle rejection
  dialog.close();
});

btnApprove.addEventListener('click', () => {
  // handle approval 
  dialog.close();
});Code language: JavaScript (javascript)

此代码应该可以正常工作,但有一些缺点

  • 处理用户交互的代码分散在事件处理程序中。
  • 关闭对话框的重复代码。

为了避免这些问题,您可以使用 Promise.withResolvers() 方法。

index.html

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>JavaScript Promise.withResolvers() method</title>
        <script src="app.js" defer></script>
    </head>
    <body>
        <button id="btnReview">Review</button>
        <dialog>
            <p>Please approve/reject this request?</p>

            <button id="btnApprove">Approve</button>
            <button id="btnReject">Reject</button>
        </dialog>
        <p id="message" hidden></p>
    </body>
</html>Code language: HTML, XML (xml)

app.js

const btnReview = document.querySelector('#btnReview');
const btnApprove = document.querySelector('#btnApprove');
const btnReject = document.querySelector('#btnReject');
const dialog = document.querySelector('dialog');

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

btnReview.addEventListener('click', () => dialog.show());
btnApprove.addEventListener('click', resolve);
btnReject.addEventListener('click', reject);

promise
  .then(() => (message.innerHTML = 'You approved it.'))
  .catch(() => (message.innerHTML = 'You rejected it.'))
  .finally(() => {
    message.hidden = false;
    dialog.close();
    btnReview.remove();
  });Code language: JavaScript (javascript)

工作原理。

首先,选择页面上的元素,包括 btnReviewbtnApprovebtnRejectdialog

const btnReview = document.querySelector('#btnReview');
const btnApprove = document.querySelector('#btnApprove');
const btnReject = document.querySelector('#btnReject');
const dialog = document.querySelector('dialog');Code language: JavaScript (javascript)

其次,使用 resolve 和 reject 函数创建一个新的 Promise

const { promise, resolve, reject } = Promise.withResolvers();Code language: JavaScript (javascript)

第三,将事件处理程序与 btnReviewbtnApprovebtnReject 按钮的点击事件连接起来

btnReview.addEventListener('click', () => dialog.show());
btnApprove.addEventListener('click', resolve);
btnReject.addEventListener('click', reject);Code language: JavaScript (javascript)

最后,使用 then()catch()finally() 方法调用 Promise 对象

promise
  .then(() => (message.innerHTML = 'You approved it.'))
  .catch(() => (message.innerHTML = 'You rejected it.'))
  .finally(() => {
    message.hidden = false;
    dialog.close();
    btnReview.remove();
  });Code language: JavaScript (javascript)

通过使用 Promise.withResolvers() 方法,我们可以实现两个目标

  • 将用户交互集中到 Promise 中。
  • 通过将重复代码移到 Promise 的 finally() 方法中来消除重复代码。

总结

  • 使用 Promise.withResolvers() 方法来创建一个新的 Promise,其中包含其 resolve 和 reject 函数。

测验

本教程是否有用?