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

无法重写Promise类方法:调用then时出现不兼容接收器错误

解决Promise.prototype.then重写的兼容性错误,实现Promise监控计数器

首先,你遇到的错误核心原因有两个:

  • 用箭头函数重写Promise.prototype.then和构造函数是错误的:箭头函数没有自己的this绑定,会导致调用then时this指向全局对象(或Postman沙箱的上下文对象),而不是Promise实例,这就触发了"incompatible receiver"错误。
  • 调用原then方法时参数传递错误:你直接把args数组作为单个参数传给call,但then需要接收两个独立的回调参数,应该展开数组。

另外,你原代码还没实现全局计数器和pending状态监控的核心需求,我会帮你把这部分补上。

修正后的完整代码

// 保存原生方法的引用
const NativePromise = Promise;
const nativeThen = Promise.prototype.then;
const nativeCatch = Promise.prototype.catch;
const nativeFinally = Promise.prototype.finally;

// 全局计数器和状态监控
const promiseMonitor = {
  total: 0,
  pending: 0,
  resolved: 0,
  rejected: 0
};

// 重写Promise构造函数
Promise = function(...args) {
  promiseMonitor.total++;
  promiseMonitor.pending++;

  const promise = new NativePromise((resolve, reject) => {
    // 包装resolve,更新状态
    const wrappedResolve = (value) => {
      promiseMonitor.pending--;
      promiseMonitor.resolved++;
      resolve(value);
    };

    // 包装reject,更新状态
    const wrappedReject = (reason) => {
      promiseMonitor.pending--;
      promiseMonitor.rejected++;
      reject(reason);
    };

    args[0](wrappedResolve, wrappedReject);
  });

  return promise;
};

// 继承原生Promise的静态方法(保持Promise.all等方法可用)
Object.assign(Promise, NativePromise);

// 重写then方法
Promise.prototype.then = function(onFulfilled, onRejected) {
  console.log("then called");
  return nativeThen.call(this, onFulfilled, onRejected);
};

// 重写catch方法(保持一致性)
Promise.prototype.catch = function(onRejected) {
  console.log("catch called");
  return nativeCatch.call(this, onRejected);
};

// 重写finally方法(保持一致性)
Promise.prototype.finally = function(onFinally) {
  console.log("finally called");
  return nativeFinally.call(this, onFinally);
};

// 测试函数
function test2(num) {
  let promise = new Promise((resolve, reject) => {
    if (num > 1) {
      setTimeout(()=> {
        resolve(num);
      }, 10);
    } else {
      reject(num);
    }
  });
  return promise;
}

// 执行测试
test2(10).then((num) => {
  console.log("Inside then");
  setTimeout(() => {
    console.log("Promise has been resolved - " + num);
    console.log("Promise Monitor Status:", promiseMonitor);
  }, 20);
});

// 测试rejected场景
test2(0).catch((num) => {
  console.log("Promise has been rejected - " + num);
  console.log("Promise Monitor Status:", promiseMonitor);
});

关键修正点说明

  1. 改用普通函数重写方法:
    不管是Promise构造函数还是then/catch/finally方法,都要用普通函数,这样才能保证this指向当前的Promise实例。
  2. 正确传递参数:
    调用原生then时,直接传递单个回调参数给call,确保参数正确传递给原生方法,避免数组作为单个参数传入的问题。
  3. 实现监控计数器:
    在构造函数中初始化计数器,通过包装resolve和reject回调来更新pending、resolved、rejected的数量,全局的promiseMonitor对象可以随时查看当前Promise的状态统计。
  4. 继承静态方法:
    通过Object.assign(Promise, NativePromise)把原生Promise的静态方法(比如Promise.all、Promise.race)复制到重写后的Promise上,避免这些方法失效。

运行效果

执行后你会看到:

  • 控制台输出then called、Inside then等日志
  • 最终promiseMonitor会显示正确的统计数据,比如total:2, pending:0, resolved:1, rejected:1(两个测试都执行的情况下)

内容的提问来源于stack exchange,提问作者Tarun Lalwani

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 04:56:02