Promise.withResolvers()
Baseline 2024
Newly available
Since March 2024, this feature works across the latest devices and browser versions. This feature might not work in older devices or browsers.
Promise.withResolvers()
静态方法返回一个对象,其中包含一个新的 Promise
对象和两个解析或拒绝它的函数,对应于传递给 Promise()
构造函数的执行器的两个参数。
¥The Promise.withResolvers()
static method returns an object containing a new Promise
object and two functions to resolve or reject it, corresponding to the two parameters passed to the executor of the Promise()
constructor.
语法
参数
返回值
描述
¥Description
Promise.withResolvers()
完全等同于以下代码:
¥Promise.withResolvers()
is exactly equivalent to the following code:
let resolve, reject;
const promise = new Promise((res, rej) => {
resolve = res;
reject = rej;
});
只是它更加简洁并且不需要使用 let
。
¥Except that it is more concise and does not require the use of let
.
使用 Promise.withResolvers()
时的主要区别在于,解决函数和拒绝函数现在与 Promise 本身位于同一范围内,而不是在执行程序中创建和使用一次。这可能会启用一些更高级的用例,例如将它们重用于重复事件时,特别是对于流和队列。与在执行器中封装大量逻辑相比,这通常也会导致更少的嵌套。
¥The key difference when using Promise.withResolvers()
is that the resolution and rejection functions now live in the same scope as the promise itself, instead of being created and used once within the executor. This may enable some more advanced use cases, such as when reusing them for recurring events, particularly with streams and queues. This also generally results in less nesting than wrapping a lot of logic within the executor.
Promise.withResolvers()
是通用的并且支持子类化,这意味着它可以在 Promise
的子类上调用,并且结果将包含子类类型的承诺。为此,子类的构造函数必须实现与 Promise()
构造函数相同的签名 - 接受可以使用 resolve
和 reject
回调作为参数进行调用的单个 executor
函数。
¥Promise.withResolvers()
is generic and supports subclassing, which means it can be called on subclasses of Promise
, and the result will contain a promise of the subclass type. To do so, the subclass's constructor must implement the same signature as the Promise()
constructor — accepting a single executor
function that can be called with the resolve
and reject
callbacks as parameters.
示例
将流转换为异步可迭代
¥Transforming a stream to an async iterable
Promise.withResolvers()
的用例是当你有一个承诺应该由某个无法封装在承诺执行器内的事件监听器解决或拒绝时。以下示例将 Node.js 可读流 转换为 异步可迭代。这里的每个 promise
代表一批可用数据,每次读取当前批次时,都会为下一批创建一个新的 Promise。请注意事件监听器仅附加一次,但实际上每次都调用不同版本的 resolve
和 reject
函数。
¥The use case of Promise.withResolvers()
is when you have a promise that should be resolved or rejected by some event listener that cannot be wrapped inside the promise executor. The following example transforms a Node.js readable stream to an async iterable. Each promise
here represents a single batch of data available, and each time the current batch is read, a new promise is created for the next batch. Note how the event listeners are only attached once, but actually call a different version of the resolve
and reject
functions each time.
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()
¥Calling withResolvers() on a non-Promise constructor
Promise.withResolvers()
是通用方法。可以在任何实现与 Promise()
构造函数相同签名的构造函数上调用它。例如,我们可以在将 console.log
作为 resolve
和 reject
函数传递给 executor
的构造函数上调用它:
¥Promise.withResolvers()
is a generic method. It can be called on any constructor that implements the same signature as the Promise()
constructor. For example, we can call it on a constructor that passes console.log
as the resolve
and reject
functions to 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
规范
Specification |
---|
ES Promise.withResolvers (2023) # sec-promise.withResolvers |
浏览器兼容性
BCD tables only load in the browser