Combine框架如何实现嵌套URL请求并整合成单个Publisher
Combine 双请求串行合并实现方法
你需要先将第二个请求封装为入参为ID集合、返回补充数据的Publisher方法,完整实现如下:
// 第二个请求封装示例,可根据你的实际业务调整实现 func getAdditionalFields(ids: [MyIDType]) -> AnyPublisher<AdditionalFields, NetworkError> { let additionalRequest = AdditionalInfoRequest(ids: ids) return networking.json(additionalRequest) .mapError { _ in NetworkError.invalidData } .eraseToAnyPublisher() } func getDataFromServer(request: Request) -> AnyPublisher<MyData, NetworkError> { return networking.xml(request) .mapError { _ in NetworkError.invalidData } .flatMap { response -> AnyPublisher<MyData, NetworkError> in // 解析第一个请求的响应 guard let data = MyData.from(response: response) else { return Fail(error: NetworkError.parseError) .eraseToAnyPublisher() } // 无需要查询的ID时直接返回已解析数据 guard !data.myID.isEmpty else { return Just(data) .setFailureType(to: NetworkError.self) .eraseToAnyPublisher() } // 发起第二个请求,合并补充字段后返回最终数据 return getAdditionalFields(ids: data.myID) .map { additionalFields in // 若MyData为值类型(struct)需声明为可变变量 var mutableData = data mutableData.fieldA = additionalFields.fieldA mutableData.fieldB = additionalFields.fieldB // 其余需要填充的字段按业务补充即可 return mutableData } .eraseToAnyPublisher() } .eraseToAnyPublisher() }
核心注意点:
- 不需要额外嵌套
Future:flatMap支持直接返回另一个Publisher,Combine会自动等待第二个请求完成后再向下传递事件,整个链路天然就是单个Publisher输出 - 错误类型统一:所有分支的失败类型都需要和方法返回的
NetworkError保持一致,空ID场景用setFailureType对齐错误类型 - 最终返回的Publisher对外输出的就是已经填充完所有字段的
MyData对象,外部直接订阅即可使用
内容的提问来源于stack exchange,提问作者ArisRS
相关产品推荐
相关产品推荐

