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
相关产品推荐
相关产品推荐

