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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 21:23:09