Calculator类calculate方法Promise实现问题求助
修复Calculator类的calculate方法以通过所有测试用例
我为编码挑战编写了一个简易Calculator类,现在需要实现一个返回Promise的calculate方法,但遇到了问题。当前编写的calculate方法仅能通过第一个测试用例,其余测试均不通过。
原Calculator类代码
class Calculator{ constructor(){ this[Symbol.toStringTag] = 'Calculator'; } add(a, b) { return a + b; } subtract(a, b) { return a - b; } multiply(a, b) { return a * b; } divide(a, b) { if(b === 0){ return NaN; } return a / b; } toString(){ return "Calculator"; } calculate(...args) { var result = 0; return new Promise(function(resolve, reject){ setTimeout(function() { if(result === NaN) { reject(NaN); } else { resolve(result); } }, 1000); }); } }
对应的测试用例
describe( "Calculator.calculate", function(){ let calculator; beforeEach( function(){ calculator = new Calculator(); } ); it( "returns a promise", function( done ){ const callDone = () => done(), calculating = calculator.calculate( () => void 0 ); expect( calculating ).to.be.instanceOf( Promise ); calculating.then( callDone ).catch( callDone ); } ); it( "resolves with the result when the calculation succeeds", function( done ){ const calculating = calculator.calculate( function(){ expect( this ).to.equal( calculator ); let result = 0; result += this.add( 1, 2 ); result += this.add( 3, 4 ); return result; } ); calculating .then( function( result ){ expect( result ).to.equal( 10 ); done(); } ) .catch( () => done() ); } ); it( "rejects with NaN when the calculation fails", function( done ){ const calculating = calculator.calculate(); calculating.catch( function( result ){ expect( result ).to.be.NaN; done(); } ); } ); } );
修正后的calculate方法
calculate(...args) { return new Promise((resolve, reject) => { setTimeout(() => { // 取出传入的回调函数 const callback = args[0]; // 未传入回调直接reject NaN if (typeof callback !== 'function') { reject(NaN); return; } try { // 绑定this到当前实例,执行回调并获取结果 const result = callback.call(this); // 正确判断NaN(NaN与任何值都不相等,包括自身) if (Number.isNaN(result)) { reject(NaN); } else { resolve(result); } } catch (err) { // 捕获回调执行中的异常,统一reject NaN reject(NaN); } }, 1000); }); }
关键修改点说明
- 处理回调参数:原代码完全忽略传入的回调,现在校验第一个参数是否为函数,非函数直接触发reject,对应第三个测试用例。
- 绑定上下文:使用
callback.call(this)确保回调内部的this指向当前Calculator实例,满足第二个测试用例对this的校验要求。 - 正确判断NaN:替换
result === NaN为Number.isNaN(result),解决NaN无法通过全等判断的问题。 - 异常捕获:增加try-catch块处理回调执行时的异常,保证异常场景下也能按要求reject NaN,提升代码鲁棒性。
内容的提问来源于stack exchange,提问作者dezratt
相关产品推荐
相关产品推荐

