译:使用 Promise.withResolvers 延迟 Promise

原文: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 执行器中嵌套,尽管当你需要将 resolvereject 传递给多个调用者时,它表现得更加出色。在流或基于事件的系统中工作是简化你的生活并使用 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 的价值以及如何在你的项目中利用这种模式。下次见,保持好奇 ✌️