使用 Promise.withResolvers() 来简化你将函数 Promise 化的实现~~

引言

在JavaScript编程中,Promise 是一种处理异步操作的常用机制。Promise 对象代表了一个尚未完成但预期将来会完成的操作的结果。在本文中,我们将探讨如何通过使用 ES2024 的 Promise.withResolvers API 来优化我们的 Promise 实现。

现有实现的问题

首先,让我们看一个简单的示例,展示在没有使用 Promise.withResolvers 时,如何实现一个函数,该函数在传入的另一个函数执行完毕后2秒才返回结果:

js 复制代码
const returnAfterTwoSeconds = (func, ...args) => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      try {
        resolve(func(...args));
      } catch (e) {
        reject(e);
      }
    }, 2000);
  });
};

虽然上述代码能够正常工作,但它的嵌套层次较深,对于初次阅读的人来说可能不够直观。

改进实现

为了提高代码的可读性,我们可以对上述实现进行一些改进:

js 复制代码
const returnAfterTwoSeconds = (func, ...args) => {
  let outerResolve = null;
  let outerReject = null;
  const promise = new Promise((resolve, reject) => {
    outerResolve = resolve;
    outerReject = reject;
  });

  setTimeout(() => {
    try {
      outerResolve(func(...args));
    } catch (e) {
      outerReject(e);
    }
  }, 2000);

  return promise;
};

在这个改进版本中,我们首先创建了一个 Promise 对象,并暂存了它的 resolve 和 reject 方法。然后在 setTimeout 中调用这些方法,最后返回 Promise 对象。这样,即使 setTimeout 中的回调执行完毕,返回的 Promise 对象也会根据回调的结果变为 resolved 或 rejected。

使用 Promise.withResolvers

现在,让我们看看如何使用 Promise.withResolvers 来进一步简化我们的代码:

js 复制代码
const returnAfterTwoSeconds = (func, ...args) => {
  const { promise, resolve, reject } = Promise.withResolvers();

  setTimeout(() => {
    try {
      resolve(func(...args));
    } catch (e) {
      reject(e);
    }
  }, 2000);

  return promise;
};

可以看到,这个方法并没有为我们的代码带来性能或者说实现方式上的优化,但是它使用起来很简单,也很好理解~ 有助于提高代码的可读性和简洁~

Promise.withResolvers 详解

根据 MDN 文档,Promise.withResolvers 的语法如下:

  • 语法:Promise.withResolvers()
  • 参数:无
  • 返回值:
    • promise: 一个 对象。
    • resolve: 一个函数,用于解决该 Promise。关于其语义,请参阅 构造函数。
    • reject: 一个函数,用于拒绝该 Promise。关于其语义,请参阅 构造函数。

自定义实现

最后,我们可以自定义一个函数来模拟 Promise.withResolvers 的行为:

js 复制代码
function myWithResolvers() {
  let resolve = null;
  let reject = null;
  const promise = new Promise((_resolve, _reject) => {
    resolve = _resolve;
    reject = _reject;
  });

  return { promise, resolve, reject };
}

可以看到,这个api在实现上其实也很简单,只是把我们平常获取promise中resolve和reject的步骤封装到一个方法中,但为我们节省了很多时间~

相关推荐
默_笙2 小时前
🚦 请三个 AI 考官给 RAG 打分:量化评估实战(下)
前端·javascript
阿坨2 小时前
灵感闪存卡:一款 Tampermonkey用户脚本
javascript·tampermonkey
朝朝辞暮i4 小时前
C++ 第 25 课:getter / setter + this
java·javascript·c++
蜗牛互联网5 小时前
Python接入Gemini 3.8 Flash实现票据视觉抽取与规则校验
java·javascript·网络·人工智能·python
xieter6 小时前
【技术精选】深入浅出现代前端渲染与性能优化实践指南 (2026-10-04)
前端·javascript
xieter6 小时前
【硬核实战】TypeScript Compiler API: Preserving Child Node Narrowing in Reusable Type Guards 🔧 (2026-10-03)
前端·javascript
xieter6 小时前
【硬核实战】React 19 useFormStatus Returning False? I Built a SubmitButton That Fixes It (2026-10-03)
前端·javascript
paopaokaka_luck8 小时前
非遗文物数字化小程序(AI非遗问答、ONNX图像识别、协同过滤推荐、ECharts数据分析、非遗知识浏览与互动、文创商城订单闭环、文化活动报名签到、社区交流)
javascript·spring boot·mysql·数据分析·echarts·mybatis
Highcharts.js8 小时前
图表开发实战总结| 7 条“黄金法则”与“性能铁律”
前端·javascript·vue.js·编辑器·时序数据库·highcharts
Helix2508 小时前
Electron、WebView 框架与 HTA 对比:桌面应用选型、安全性与现代替代方案
前端·javascript·electron·webview·vbscript·hta·本地html应用