Combine中如何结合flatMap/Scan传递中间结果?链式HTTP请求进阶处理
解决RxSwift链式调用中传递上下文数据的问题
嗨,这个场景我太熟悉了——用flatMap串请求时,经常需要把前面步骤的结果带到后面的操作里,默认的链式只能拿到上一步的输出,确实头疼。下面给你两种最实用的解决方案:
方法一:用元组打包需要传递的数据
如果要传递的数据不多,元组是最轻便的方式,直接把需要保留的上下文和当前请求结果打包返回,让下一个flatMap能同时拿到两者:
getAPIKey() .flatMap { key -> Observable<(String, Data1)> in // 将key和getData1的结果打包成元组返回 return getData1(key).map { data1 in (key, data1) } } .flatMap { (key, data1) -> Observable<Data2> in // 这里就能同时使用key和data1调用getData2了 return getData2(key, data1) } .map { data2 in data2.transform() } .subscribe(onNext: { transformedData in // 处理最终转换后的数据 print(transformedData) })
方法二:用自定义结构体封装上下文(推荐复杂场景)
如果需要传递的数据比较多,或者后续还有更多步骤,元组会变得难以阅读和维护,这时候可以定义一个专门的结构体来保存所有需要的上下文数据:
// 定义上下文结构体,按需添加需要传递的字段 struct RequestContext { let apiKey: String let data1: Data1 // 如果后续还有需要传递的数据,直接在这里加字段即可 } getAPIKey() .flatMap { key -> Observable<RequestContext> in getData1(key).map { data1 in RequestContext(apiKey: key, data1: data1) } } .flatMap { context -> Observable<Data2> in // 从context中直接取出需要的apiKey和data1 return getData2(context.apiKey, context.data1) } .map { $0.transform() } .subscribe(onNext: { transformed in // 执行后续操作 })
核心思路
问题的本质是:默认的flatMap只会将上一个Observable的输出(也就是getData1(key)的结果)传递给下一个操作,所以我们需要主动把前面的上下文(比如key)和当前结果打包在一起,让后续操作能拿到完整的依赖数据。
两种方法各有优劣:元组适合简单场景,代码更简洁;自定义结构体适合复杂场景,可读性和扩展性更强,后续修改也更方便。
内容的提问来源于stack exchange,提问作者Tommy Sadiq Hinrichsen
相关产品推荐
相关产品推荐

