Swift Combine:如何合并多个AnyPublisher并统一接收数据
Combine多组请求合并实现方案
针对你需要同时发起多组请求并统一接收数据的场景,可以分两步合并Publisher:先批量合并同类型请求,再合并不同类型的结果集。
步骤1:批量合并同类型请求
对于需要批量调用的fetchStandarts和fetchAccessibilities,使用Publishers.ZipMany将多个同类型Publisher合并为一个,等所有批量请求完成后输出所有结果的数组:
// 合并所有标准列表请求,输出结果为 [[A11yStandart]] let standardsCombined = Publishers.ZipMany(standardsPublishers) .eraseToAnyPublisher() // 合并所有无障碍信息请求,输出结果为 [AccessibilitiesResult] let accessibilitiesCombined = Publishers.ZipMany(answersPublishers) .eraseToAnyPublisher()
步骤2:合并所有类型的结果
将批量合并后的两个Publisher,与单个图片请求的Publisher,通过Publishers.Zip3合并,这样三个请求组全部完成后会统一返回包含所有结果的元组:
// 合并三个请求组,输出元组包含三个结果 let combinedAll = Publishers.Zip3(standardsCombined, accessibilitiesCombined, imagesPublisher) .sink(receiveCompletion: { completion in switch completion { case .failure(let error): // 处理任何请求失败的情况 print("请求失败:\(error)") case .finished: print("所有请求完成") } }, receiveValue: { (standardsResults, accessibilitiesResults, imagesResult) in // 统一处理所有结果 // standardsResults: [[A11yStandart]] 所有标准列表请求的结果数组 // accessibilitiesResults: [AccessibilitiesResult] 所有无障碍信息请求的结果数组 // imagesResult: AccessibilityImagesResult 图片请求的结果 print("标准列表结果:\(standardsResults)") print("无障碍信息结果:\(accessibilitiesResults)") print("图片信息结果:\(imagesResult)") })
注意事项
ZipMany要求所有输入的Publisher输出类型一致,且会等待所有Publisher都完成后才输出结果,适合需要批量统一获取数据的场景;如果需要每个请求完成就处理,可以用MergeMany,但那样无法统一等待所有请求完成。Zip3会等待三个输入的Publisher都完成后才输出元组,只要其中一个请求失败,整个合并流会进入失败状态。如果需要容错(比如部分请求失败不影响整体),可以给单个请求添加catch处理,返回默认值或空结果:
// 给单个请求添加容错处理示例 let standardsPublishers = ["1", "2"] .map { key -> AnyPublisher<[A11yStandart], APIError> in a11yStandartsRepository.fetchStandarts(by: key) .catch { _ in Just([]).setFailureType(to: APIError.self) } .eraseToAnyPublisher() }
内容的提问来源于stack exchange,提问作者user24060880
相关产品推荐
相关产品推荐

