Promise.withResolvers()
Promise.withResolvers()
静态方法返回一个对象,其中包含一个新的 Promise
对象以及两个用于解析或拒绝它的函数,分别对应于传递给 Promise()
构造函数执行器的两个参数。
语法
Promise.withResolvers()
参数
无。
返回值
描述
Promise.withResolvers()
与以下代码完全等效
let resolve, reject;
const promise = new Promise((res, rej) => {
resolve = res;
reject = rej;
});
不同之处在于它更简洁,不需要使用 let
。
使用 Promise.withResolvers()
时的主要区别在于,解析和拒绝函数现在与 Promise 本身位于同一作用域中,而不是在执行器中创建和使用一次。这可能会使一些更高级的用例成为可能,例如在将它们重复用于重复事件时,特别是对于流和队列而言。这也通常会导致比在执行器中包装大量逻辑更少的嵌套。
Promise.withResolvers()
是通用的,支持子类化,这意味着它可以在 Promise
的子类上调用,结果将包含子类类型的 Promise。为此,子类的构造函数必须实现与 Promise()
构造函数相同的签名——接受一个可以调用 resolve
和 reject
回调作为参数的 executor
函数。
示例
将流转换为异步可迭代对象
Promise.withResolvers()
的用例是当您有一个应该由某些事件监听器解析或拒绝的 Promise 时,该事件监听器无法包装在 Promise 执行器内部。以下示例将 Node.js 可读流 转换为 异步可迭代对象。这里的每个 promise
都代表一批可用的数据,每次读取当前批次时,都会为下一批次创建一个新的 Promise。请注意,事件监听器只附加一次,但每次实际上调用 resolve
和 reject
函数的不同版本。
async function* readableToAsyncIterable(stream) {
let { promise, resolve, reject } = Promise.withResolvers();
stream.on("error", (error) => reject(error));
stream.on("end", () => resolve());
stream.on("readable", () => resolve());
while (stream.readable) {
await promise;
let chunk;
while ((chunk = stream.read())) {
yield chunk;
}
({ promise, resolve, reject } = Promise.withResolvers());
}
}
在非 Promise 构造函数上调用 withResolvers()
Promise.withResolvers()
是一个通用方法。它可以在任何实现与 Promise()
构造函数相同的签名的构造函数上调用。例如,我们可以在将 console.log
作为 resolve
和 reject
函数传递给 executor
的构造函数上调用它
class NotPromise {
constructor(executor) {
// The "resolve" and "reject" functions behave nothing like the native
// promise's, but Promise.withResolvers() just returns them, as is.
executor(
(value) => console.log("Resolved", value),
(reason) => console.log("Rejected", reason),
);
}
}
const { promise, resolve, reject } = Promise.withResolvers.call(NotPromise);
resolve("hello");
// Logs: Resolved hello
规范
规范 |
---|
ES Promise.withResolvers (2023) # sec-promise.withResolvers |
浏览器兼容性
BCD 表仅在启用 JavaScript 的浏览器中加载。