无法重写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); });
关键修正点说明
- 改用普通函数重写方法:
不管是Promise构造函数还是then/catch/finally方法,都要用普通函数,这样才能保证this指向当前的Promise实例。 - 正确传递参数:
调用原生then时,直接传递单个回调参数给call,确保参数正确传递给原生方法,避免数组作为单个参数传入的问题。 - 实现监控计数器:
在构造函数中初始化计数器,通过包装resolve和reject回调来更新pending、resolved、rejected的数量,全局的promiseMonitor对象可以随时查看当前Promise的状态统计。 - 继承静态方法:
通过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
相关产品推荐
相关产品推荐

