Swift 5中API请求回调嵌套问题优化与集合视图刷新方案咨询
问题1:Swift 5 不使用async/await避免回调地狱的方案
- 拆分嵌套逻辑为独立函数:不要把所有后续异步任务的实现都写在前一个任务的闭包内,每一层任务的后续逻辑都抽成单独的命名函数,回调里直接调用抽离后的函数即可,不会出现多层缩进嵌套的问题。
- 使用Promise/Future封装异步任务:可以接入第三方库PromiseKit,或者自行实现轻量的Future类型,每个异步任务返回一个Promise对象,通过
.then链式调用串联后续任务,代码结构完全扁平,还可以统一处理错误。示例代码如下:
// 链式调用示例,无嵌套结构 fetchEvents() .then(doTask1) .then(doTask2) .done { finalResult in // 所有任务完成后的处理 } .catch { error in // 统一处理全链路异常 }
- 使用OperationQueue管理异步任务:将每个异步任务封装为自定义的异步Operation,通过
addDependency方法设置任务之间的依赖关系,最后将所有Operation加入队列即可自动按顺序执行,无需嵌套回调。 - 使用Combine框架(iOS 13+支持):将异步任务封装为Publisher,通过
flatMap等操作符串联多个异步任务,链式结构扁平,同时支持线程切换、错误处理、数据变换等能力。
问题2:当前集合视图刷新逻辑的优化写法
你当前的实现是可以正常运行的,可从以下角度简化优化:
- 移除全局events状态依赖,直接通过回调传递请求结果,避免多端修改状态导致的不同步问题,同时逻辑更内聚:
func populateCV() { fetchEvents { [weak self] events in guard let self = self else { return } var snapshot = NSDiffableDataSourceSnapshot<Section, Event>() snapshot.appendItems(events) self.collectionViewDataSource?.apply(snapshot) } } func fetchEvents(completion: @escaping ([Event]) -> Void) { // Alamofire请求拿到result后 DispatchQueue.main.async { completion(results) } }
- 抽离UI刷新逻辑,进一步简化调用:
// 单独封装刷新集合视图的方法 func updateCV(with events: [Event]) { var snapshot = NSDiffableDataSourceSnapshot<Section, Event>() snapshot.appendItems(events) collectionViewDataSource?.apply(snapshot) } // 调用时无需写闭包,直接传入方法即可 func populateCV() { fetchEvents(completion: updateCV) }
内容的提问来源于stack exchange,提问作者Yuuu
相关产品推荐
相关产品推荐

