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

RxSwift中Observable.zip多API调用的成败场景处理方法咨询

解决Observable.zip无法单独获取每个API调用结果的问题

Observable.zip的特性是只要其中一个序列发送error事件,整个组合序列就会终止并触发onError,导致无法获取其他序列的结果。要实现单独追踪每个API的成功/失败状态,核心思路是将每个API的错误事件包装成正常的结果事件,避免子序列直接发送error。

步骤1:定义结果封装枚举

先创建一个枚举来统一包装API的成功和失败状态:

enum APIResult<T> {
    case success(T)
    case failure(Error)
}

步骤2:包装每个API请求

对每个原API请求进行包装,用catch操作符捕获错误,并将其转换成APIResult.failure事件发送,确保子序列不会抛出error:

// 包装第一个API
let wrappedApi1 = api1()
    .map { APIResult.success($0) }
    .catch { error in
        return Observable.just(APIResult.failure(error))
    }

// 包装第二个API
let wrappedApi2 = api2()
    .map { APIResult.success($0) }
    .catch { error in
        return Observable.just(APIResult.failure(error))
    }

步骤3:用zip组合并处理结果

此时用Observable.zip组合两个包装后的序列,无论单个API成功或失败,zip都会等待两个序列都发送事件后,将结果合并传递到onNext中,你可以在这里单独处理每个API的状态:

Observable.zip(wrappedApi1, wrappedApi2)
    .subscribe(onNext: { result1, result2 in
        // 处理第一个API的结果
        switch result1 {
        case .success(let response):
            print("API1请求成功: \(response)")
        case .failure(let error):
            print("API1请求失败: \(error.localizedDescription)")
        }
        
        // 处理第二个API的结果
        switch result2 {
        case .success(let response):
            print("API2请求成功: \(response)")
        case .failure(let error):
            print("API2请求失败: \(error.localizedDescription)")
        }
    })
    .disposed(by: disposeBag)

简化写法(无需单独定义包装变量)

也可以直接在zip调用内完成包装,让代码更紧凑:

Observable.zip(
    api1().map(APIResult.success).catch { Observable.just(.failure($0)) },
    api2().map(APIResult.success).catch { Observable.just(.failure($0)) }
)
.subscribe(onNext: { result1, result2 in
    // 同上处理逻辑
})
.disposed(by: disposeBag)

这种方式既保留了zip等待所有序列完成的特性,又能完整获取每个API的独立结果状态,不会因为单个API失败而丢失其他请求的信息。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 00:13:23