Promise出了个新方法:Promise.withResolvers()

更新日期: 2024-02-18阅读: 738标签: Promise

有时候我们需要把 Promise 的 resolve 或者 reject 这两个参数给取出来,比如:

let resolve, reject;
const promise = new Promise((res, rej) => {
resolve = res;
reject = rej;
});
Math.random() > 0.5 ? resolve("ok") : reject("not ok");

这样挺麻烦的,总是定义额外变量去存储这个 resolve,reject。但在 Chrome 119(发布于2023年10月31日)版本之后,可以使用以下方式实现:

const { promise, resolve, reject } = Promise.withResolvers();
Math.random() > 0.5 ? resolve("ok") : reject("not ok");

是不是更简洁,可以看出Promise.withResolvers()的主要作用是把 Promise实例、resolve、reject 解构出来供我们使用。它是一个静态方法,返回一个包含新的 Promise 对象和两个函数的对象,用于解决或拒绝该 Promise。这两个函数对应于传递给 Promise() 构造函数的执行器的两个参数。

Promise.withResolvers 的关键区别在于现在解决和拒绝函数与 Promise 对象本身处于同一作用域,而不是在执行器中创建并且只能使用一次。这使得在某些更高级的用例中可能会更加方便,例如在重复事件中重用解决和拒绝函数,特别是在处理流和队列时。这通常也意味着嵌套层级较少,而不是在执行器中包含大量逻辑。

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 的示例中,将 Node.js 的可读流转换为异步可迭代对象。每个 promise 代表一批可用的数据,每次读取当前批次时,将创建一个新的 promise 用于下一个批次。请注意,事件监听器只添加了一次,但实际上每次都会调用不同版本的解决和拒绝函数。
此外,Promise.withResolvers 也适用于非 Promise 构造函数。可以在任何实现了与 Promise() 构造函数相同签名的构造函数上调用它。例如,我们可以在一个将 console.log 作为解决和拒绝函数传递给执行器的构造函数上调用它。

class NotPromise {
constructor(executor) {
// “resolve”和“reject”函数和原生的 promise 的行为完全不同
// 但 Promise.withResolvers() 只是返回它们,就像是原生的 promise 一样
executor(
(value) => console.log("以", value, "解决"),
(reason) => console.log("以", reason, "拒绝"),
);
}
}

const { promise, resolve, reject } = Promise.withResolvers.call(NotPromise);
resolve("hello");
// 输出:以 hello 解决

总而言之,Promise.withResolvers 提供了一种更简洁、更高级的方式来处理 Promise 的解决和拒绝,并且支持更多灵活的用例,使代码更易于阅读和维护。

Promise.withResolvers这个新api,目前处于Stage-3阶段,需要谷歌 117 以上的版本才能使用这个方法,Stage-3就是候选的意思,这些方法的提案分为几个阶段

  • Stage 0 - Strawman (草案阶段): 这是提案的初始阶段,通常是一些初步的想法或建议。这些提案还没有得到正式的讨论和接受。
  • Stage 1 - Proposal (提案阶段): 在这个阶段,提案已经经过了初步的讨论,并且有了详细的说明。它们通常由一个或多个TC39委员会成员提交,并等待进一步的审查和反馈。
  • Stage 2 - Draft (草案阶段): 在这个阶段,提案已经经过了初步的审查,包括语法和语义方面的考虑。提案可能会在这个阶段进行一些修改和改进。
  • Stage 3 - Candidate (候选阶段): 当提案达到这个阶段时,它们被认为是成熟的,可以被实施到JavaScript引擎中。这通常包括详细的规范文档和实际的参考实现。
  • Stage 4 - Finished (完成阶段): 这是提案的最终阶段,表示它们已经被正式接受为ECMAScript标准的一部分,可以在各种JavaScript环境中广泛使用。

期待不久的将来,这个方法能到Stage 4阶段,并在项目中广泛使用!

链接: https://fly63.com/article/detial/12646

你真的了解 Promise 吗?Promise 必知必会(十道题)

Promise 想必大家十分熟悉,想想就那么几个 api,可是你真的了解 Promise 吗?本文根据 Promise 的一些知识点总结了十道题,看看你能做对几道。

剖析Promise内部结构,一步一步实现一个完整的、能通过所有Test case的Promise类

本文写给有一定Promise使用经验的人,如果你还没有使用过Promise,这篇文章可能不适合你,Promise标准中仅指定了Promise对象的then方法的行为,其它一切我们常见的方法/函数都并没有指定.

Async/Await替代Promise的6个理由

Async/Await替代Promise的6个理由:Async/Await是近年来JavaScript添加的最革命性的的特性之一。它会让你发现Promise的语法有多糟糕,而且提供了一个直观的替代方法。

Promise 原理解析与实现(遵循Promise/A+规范)

Promise是JS异步编程中的重要概念,异步抽象处理对象,是目前比较流行Javascript异步编程解决方案之一,Promise 是一个构造函数, new Promise 返回一个 promise对象 接收一个excutor执行函数作为参数

简单模仿实现 Promise 的异步模式

这篇文章是考虑如何自己实现一个简单 Promise,用以理解 Promise。和原生 Promise的调用方法一样,支持链式调用,本文实现的方法只能用于参考Promise的原理,还有很多特性没有实现,比如 race,all 方法的实现。

数组的遍历你都会用了,那Promise版本的呢

在对数组进行一些遍历操作时,发现有些遍历方法对Promise的反馈并不是我们想要的结果。async/await为Promise的语法糖,文中会直接使用async/await替换Promise;map可以说是对Promise最友好的一个函数了,

Promise使用时应注意的问题

最近在使用axios库时遇到了个问题,后端接口报了500错误,但前端并未捕获到。在axios整体配置的代码中,过滤http code时,调用了filter401()、filter500(),但是这里注意并未将两个filter函数的结果返回,也就是并未返回promise,这就是导致问题出现的原因

es6 Promise 的基础用法

想必接触过Node的人都知道,Node是以异步(Async)回调著称的,其异步性提高了程序的执行效率,但同时也减少了程序的可读性。如果我们有几个异步操作,并且后一个操作需要前一个操作返回的数据才能执行

关于 Promise 的 9 个提示

你可以在 .then 里面 return 一个 Promise,每次执行 .then 的时候都会自动创建一个新的 Promise,对调用者来说,Promise 的 resolved/rejected 状态是唯一的,Promise 构造函数不是解决方案,使用 Promise.resolve

手写一款符合Promise/A+规范的Promise

Promise的一些用法在此不多赘述,本篇主要带领你手写一个Promise源码,学完你就会发现:Promise没有你想象中的那么难.本篇大概分为以下步骤:实现简单的同步Promise、增加异步功能、增加链式调用then、增加catch finally方法、增加all race 等方法、实现一个promise的延迟对象defer、最终测试

点击更多...

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!