如何重构Combine函数,使其支持批量处理Int数组类型的cID参数
重构Combine函数以批量处理ID数组
需求回顾
现有单个ID同步函数:
func synch(cID: Int) -> AnyPublisher<Void, Error> { summariesCache .lastUpdateTimestamp(cID: cID) .prefix(1) .flatMap { self.sendRequest(withTimestamp: $0, cID: cID) } .map { self.cache.uCache(with: $0.data) } .eraseToAnyPublisher() }
需要修改为接收[Int]类型的ID数组,对每个ID执行原逻辑,全部完成后返回AnyPublisher<Void, Error>,效果等价于用DispatchGroup等待所有异步任务完成。
重构后的实现
func synch(cIDs: [Int]) -> AnyPublisher<Void, Error> { // 将ID数组转为Combine可处理的序列Publisher Publishers.Sequence(sequence: cIDs) // 对每个ID执行原同步逻辑(默认并发执行) .flatMap { cID in self.synch(cID: cID) } // 等待所有子任务完成,收集结果 .collect() // 转换为Void输出,只关心完成状态 .map { _ in () } .eraseToAnyPublisher() }
关键细节说明
Publishers.Sequence:把普通的ID数组转换成Combine Publisher,让我们能用操作符批量处理每个元素flatMapvsconcatMap:- 默认用
flatMap会并发执行所有子任务,效率更高 - 如果需要按数组顺序串行执行(处理完一个ID再处理下一个),把
flatMap换成concatMap即可
- 默认用
- 错误处理:只要任意一个子任务抛出错误,整个Publisher会立刻终止并传递该错误,和DispatchGroup中任务失败的行为一致。如果需要忽略单个错误继续执行其他任务,可以在
flatMap内添加catch处理:.flatMap { cID in self.synch(cID: cID) .catch { error -> AnyPublisher<Void, Never> in print("处理ID \(cID)失败: \(error)") return Just(()).eraseToAnyPublisher() } } // 此时返回值需调整为AnyPublisher<Void, Never>,或根据需求处理错误
内容的提问来源于stack exchange,提问作者Vader20FF
相关产品推荐
相关产品推荐

