能否通过RxSwift先获取游戏列表,再循环获取全部游戏详情?
RxSwift实现“获取分页游戏列表→批量获取游戏详情”流程
当然可以用RxSwift实现这个流程,通过操作符就能优雅地串联两个异步请求环节,以下是具体实现方案:
核心实现代码
1. 并行获取所有游戏详情
适合对请求并发数无严格限制的场景,所有详情请求会同时发起:
// 以获取第1页游戏列表为例 fetchAllGamesWithPagination(1) .flatMapLatest { games in // 将游戏列表数组拆分为单个元素的Observable序列 Observable.from(games) } .flatMap { game in // 对每个游戏ID发起详情请求 fetchGameDetails(game.id) } .subscribe( onNext: { gameDetail in // 逐个接收返回的游戏详情 print("已获取游戏详情:\(gameDetail.name)") }, onError: { error in // 处理请求错误(列表请求或任意详情请求失败都会触发) print("请求异常:\(error.localizedDescription)") }, onCompleted: { print("所有游戏详情请求完成") } ) .disposed(by: disposeBag)
2. 串行获取所有游戏详情
避免同时发起过多请求(防止触发接口限流),前一个详情请求完成后再发起下一个:
fetchAllGamesWithPagination(1) .flatMapLatest { Observable.from($0) } .concatMap { game in fetchGameDetails(game.id) } .subscribe( onNext: { gameDetail in print("已获取游戏详情:\(gameDetail.name)") }, onError: { error in print("请求异常:\(error.localizedDescription)") }, onCompleted: { print("所有游戏详情请求完成") } ) .disposed(by: disposeBag)
3. 收集所有详情为数组后一次性返回
如果需要等所有详情请求完成后统一处理结果:
fetchAllGamesWithPagination(1) .flatMapLatest { Observable.from($0) } .concatMap { fetchGameDetails($0.id) } .toArray() .subscribe( onNext: { allGameDetails in // 一次性拿到所有游戏详情数组 print("所有游戏详情已收集完成,共\(allGameDetails.count)条") }, onError: { error in print("请求异常:\(error.localizedDescription)") } ) .disposed(by: disposeBag)
关键操作符说明
flatMapLatest:将列表请求的结果(数组)转换为单个元素的序列,同时自动取消前一个未完成的列表请求(如果有重复调用的情况)Observable.from:将数组拆分为逐个发射元素的ObservableflatMap:并行处理每个元素的详情请求concatMap:串行处理每个元素的详情请求,保证顺序toArray:将所有发射的元素收集为一个数组,在序列完成时一次性发射
容错扩展建议
如果需要允许单个详情请求失败不影响整体流程,可以为fetchGameDetails添加错误处理:
// 修改详情请求的错误处理,返回空模型或默认值 func fetchGameDetailsWithFallback(_ id: Int) -> Observable<GameDetailModel?> { fetchGameDetails(id) .catchAndReturn(nil) // 请求失败时返回nil }
然后在流程中使用这个容错版方法即可。
内容的提问来源于stack exchange,提问作者Dary Winata
相关产品推荐
相关产品推荐

