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

JavaScript中如何结合setTimeout使用自定义Promise并处理错误?

问题分析与修复方案

一、关于delay函数仅使用resolve的疑问

标准Promise构造函数确实接受(resolve, reject)两个参数,但并非强制要求同时使用。这个delay函数的作用只是单纯延迟一段时间后完成,不存在失败场景——setTimeout本身不会抛出错误,因此只需要在延迟结束后触发resolve即可,这种写法完全合理。

二、addPromise函数的错误与修复

你的代码存在多个语法和逻辑问题,导致IDE报错与测试失败:

  1. 未返回Promise实例:addPromise内部调用了delay(100)但没有返回这个Promise链,外部调用时会得到undefined,而非Promise,直接导致后续.then()调用异常。
  2. 语法错误:.then()语句末尾多了分号,导致后续.catch()成为独立无效语句。
  3. 无效的reject调用:.catch()中的reject未定义,且你不在Promise构造函数内部,无需手动调用reject。
  4. 同步错误无法被Promise捕获:add函数的参数校验是同步抛出错误,若直接调用,错误不会进入Promise的catch流程。

修复后的addPromise代码

const delay = t => new Promise(resolve => setTimeout(resolve, t));

function numbersValidation(number1, number2) {
  if (!Number.isFinite(number1) || !Number.isFinite(number2)) {
    throw new Error('Only numbers are allowed');
  }
}

function add(number1, number2) {
  numbersValidation(number1, number2);
  return number1 + number2;
}

const addPromise = (number1, number2) => {
  // 返回整个Promise链,让外部能获取到Promise实例
  return delay(100)
    .then(() => {
      // 用try/catch包裹同步调用,将同步错误转为Promise的reject
      try {
        return add(number1, number2);
      } catch (err) {
        throw err; // 抛出后会自动进入Promise的错误流程
      }
    });
};

更简洁的async/await写法(本质仍是Promise):

const addPromise = async (number1, number2) => {
  await delay(100);
  return add(number1, number2); // 同步错误会自动转为Promise的reject
};

三、测试代码优化

可以简化测试中的try/catch,直接返回Promise让测试框架自动处理:

describe.only('promise calculator', () => {
  it('add works fine', () => {
    return addPromise(1, 2).then(result => {
      assert.equal(3, result);
    });
  });

  it('should reject when non-numbers are passed', () => {
    return addPromise('a', 2).catch(err => {
      assert.equal(err.message, 'Only numbers are allowed');
    });
  });
});

关键知识点总结

  • Promise构造函数的reject参数是可选的,无失败场景时可仅使用resolve。
  • Promise链必须返回,否则外部无法获取到Promise实例。
  • 同步抛出的错误需用try/catch捕获并转为Promise错误,或通过async/await自动处理。
  • 测试Promise时,直接返回Promise给测试框架即可,无需手动调用done。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 21:45:37