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

Angular函数可否部分异步?异步方法抛错及测试捕获失败如何解决

问题解答

1. async 标记的合理性判断

仅为了等待createProduct返回值给整个方法加async是完全合理的,这是async/await语法的标准使用场景,没有任何问题。
你担心的「开头直接throw Error」写法本身没有语法错误,这是JavaScript的规定:async函数内部所有同步抛出的错误,都会被自动封装为rejected状态的Promise返回,不属于错误写法,只是你需要用适配Promise的异常捕获逻辑来处理这个错误,不能用普通同步函数的异常捕获方式。

2. 单元测试报错的原因

你当前用的同步toThrowError断言,只能捕获普通同步函数直接抛出的错误。而doCreateProduct是async函数,不管是开头同步抛错还是await阶段异步抛错,调用后都会返回Promise,错误不会同步抛出到外层,所以会触发未处理的Promise rejection报错。

3. 修复方案

3.1 日常调用时的异常捕获

调用async函数时,必须用异步异常捕获的写法:

// 方案1:await + try/catch (最常用)
async function invokeCreate() {
  try {
    await service.doCreateProduct()
    // 后续成功逻辑
  } catch (err) {
    // 捕获所有错误,包括开头同步抛出的Cannot Proceed
    console.error(err.message)
  }
}

// 方案2:用Promise的catch方法
service.doCreateProduct()
  .then(() => { /* 成功逻辑 */ })
  .catch(err => { /* 捕获错误 */ })

3.2 单元测试修正

主流测试框架(Jest、Jasmine等)都支持异步断言,推荐用async/await配合rejects断言的写法:

describe('When cannot proceed', () => {
  it('should throw error', async () => {
    // 等待Promise rejected,再断言错误内容
    await expect(service.doCreateProduct()).rejects.toThrowError("Cannot Proceed");
  });
});

如果习惯用done回调的写法,也可以用如下方式:

describe('When cannot proceed', () => {
  it('should throw error', (done) => {
    service.doCreateProduct().catch(err => {
      expect(err.message).toBe("Cannot Proceed");
      done();
    })
  });
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 05:39:03