You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让浏览器原生函数使用重定义的Promise类?

问题

通过猴子补丁重定义全局Promise类后,浏览器的fetch、document.hasStorageAccess等原生函数返回的Promise并不会使用这个自定义类。示例代码如下:

Promise = class extends Promise {
  constructor(executor) {
    console.log("Promise created");
    super(executor);
  }
}
console.log("Non-native promise");
Promise.resolve(1); // 会打印"Promise created"
console.log("Native promise");
fetch("https://httpbin.org/delay/1"); // 无打印
console.log("Native promise");
document.hasStorageAccess(); // 无打印

在浏览器环境中,Promise.resolve创建的实例会走自定义构造函数,但原生API返回的Promise完全不受影响(Node.js中fetch的行为取决于具体实现,可能不同)。请问有没有办法让这些原生函数也使用自定义的Promise类?

答案

浏览器原生API内部直接调用底层原生Promise实现,不会读取全局Promise变量,所以单纯重定义全局Promise无法影响它们。可行的方案是逐个包装原生API,将其返回的原生Promise转换为自定义Promise实例:

包装fetch

const originalFetch = window.fetch;
window.fetch = (...args) => {
  return new Promise((resolve, reject) => {
    originalFetch(...args).then(resolve).catch(reject);
  });
};

包装document.hasStorageAccess

const originalHasStorageAccess = document.hasStorageAccess;
document.hasStorageAccess = function(...args) {
  return new Promise((resolve, reject) => {
    originalHasStorageAccess.call(this, ...args).then(resolve).catch(reject);
  });
};

这样调用原生API时,它们返回的原生Promise会被包装成自定义Promise实例,从而触发你重定义的构造函数逻辑。

需要注意:这种方法需要手动包装所有需要拦截的原生API,没有通用的钩子可以一次性修改所有原生Promise的创建逻辑——因为浏览器原生API的Promise创建逻辑是封装在底层实现中的,并未对外暴露可修改的接口。


内容的提问来源于stack exchange,提问作者Heiko Theißen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 21:12:14