原文:https://pawelgrzybek.com/deferred-javascript-promises-using-promise-withresolvers/
作者:Paweł Grzybek
译者:ChatGPT 4 Turbo
如果您已经在 Web 平台上开发了足够长的时间,您可能还记得 jQuery.Deferred()
或 bluebird Promise.defer()
。也许您过去使用过 p-defer
包,或者自己实现过类似下面的代码?
let resolve, reject;
const promise = new Promise((res, rej) => {
resolve = res;
reject = rej;
});
Math.random() > 0.5 ? resolve("ok") : reject("not ok");
不再需要这种方式了。 Promise.withResolvers()
将成为即将到来的 ECMAScript 2024 的一部分,因为这个提案最近达到了第 4 阶段。下面的代码片段是上面代码的等效物。
const { promise, resolve, reject } = Promise.withResolvers();
Math.random() > 0.5 ? resolve("ok") : reject("not ok");
Promise.withResolvers 使用场景
你可以使用它来避免在 promise 执行器中嵌套,尽管当你需要将 resolve
或 reject
传递给多个调用者时,它表现得更加出色。在流或基于事件的系统中工作是简化你的生活并使用 Promise.withResolvers()
的绝佳机会。
看看这个 createEventsAggregator
的例子。它返回一个 add
方法来推送新事件和一个 abort
方法来取消聚合。最重要的是,它返回一个 events
,当达到 eventsCount
限制时解决,或者当 abort
被触发时拒绝。
function createEventsAggregator(eventsCount) {
const events = [];
const { promise, resolve, reject } = Promise.withResolvers();
return {
add: (event) => {
if (events.length < eventsCount) events.push(event);
if (events.length === eventsCount) resolve(events);
},
abort: () => reject("Events aggregation aborted."),
events: promise,
};
}
const eventsAggregator = createEventsAggregator(3);
eventsAggregator.events
.then((events) => console.log("Resolved:", events))
.catch((reason) => console.error("Rejected:", reason));
eventsAggregator.add("event-one");
eventsAggregator.add("event-two");
eventsAggregator.add("event-three"); // Resolved: [ "event-one", "event-two", "event-three" ]
const eventsAggregator = createEventsAggregator(3);
eventsAggregator.events
.then((events) => console.log("Resolved:", events))
.catch((reason) => console.error("Rejected:", reason));
eventsAggregator.add("event-one");
eventsAggregator.abort();
eventsAggregator.add("event-two");
eventsAggregator.add("event-three"); // Rejected: Events aggregation aborted.
我希望这个例子能帮助你理解延迟 Promise 的价值以及如何在你的项目中利用这种模式。下次见,保持好奇 ✌️