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

如何在RxJS的finalize()中执行Observable请求或实现类似逻辑?

RxJS 链式处理两个 Observable 请求的优化实现

需求说明

需要链式处理两个类型为 Observable<void> 的请求,满足以下规则:

  • 始终执行请求A
  • 请求A执行完成后(无论A是否报错),必须执行请求B,类似 finalize() 的行为
  • 若A报错 E_A,整个流最终抛出 E_A
  • 若A成功但B报错 E_B,整个流最终抛出 E_B(也可接受流成功的情况)
  • 若两者均报错,整个流最终抛出 E_A

原实现方案

用户已实现的方案逻辑可行,但代码较为繁琐:

// 修改后端状态的请求,可能失败
const reqA: Observable<void> = this.mutateSystemState();

// 加载并渲染系统状态的请求
const reqB: Observable<void> = this.updateSystemStateDisplay();

const pipeline = reqA.pipe(
    catchError(e => of({ errA: e })),
    mergeMap(resultA => reqB.pipe(
        catchError(e => of({ errB: e })),
        map(resultB => {
            if (resultA instanceof Object) {
                throw resultA.errA;
            } else if (resultB instanceof Object) {
                throw resultB.errB;
            }
        })
    ))
);

优化后的实现方案

利用 RxJS 原生操作符组合,更简洁地实现需求逻辑:

const pipeline = reqA.pipe(
  // 捕获A的错误:先执行B,再抛出A的错误
  catchError(errA => 
    reqB.pipe(
      ignoreElements(), // 忽略B的成功输出,不影响最终抛出A的错误
      concat(throwError(() => errA))
    )
  ),
  // A成功后,执行B;B的错误会直接向上抛出
  concat(reqB)
);

逻辑解析

  1. 处理A报错的情况:当A抛出错误时,catchError 会先执行 reqB,通过 ignoreElements() 忽略B的成功结果,随后通过 concat(throwError(() => errA)) 抛出A的错误,满足「A报错时执行B且最终抛E_A」「两者都报错时抛E_A」的要求
  2. 处理A成功的情况:A执行成功后,进入 concat(reqB) 执行B;若B报错则直接抛出该错误,若B成功则整个流正常完成,满足「A成功后执行B」「B报错则抛E_B」的要求
  3. 全局规则满足:无论A成功或失败,B都会被执行,且错误优先级完全符合需求

内容的提问来源于stack exchange,提问作者Good Night Nerd Pride

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 15:35:24