You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Observable的flatMap链式调用中获取所有前置结果?

How to Capture All Previous Responses in RxSwift FlatMap Chains

Hey there! Let’s tackle this common RxSwift scenario—you’ve got a chain of dependent flatMap calls, and you want to access all the previous responses when you get to the final subscription. Here are two straightforward, clean approaches to make that happen:

Option 1: Use Tuples to Carry Forward Responses

Tuples are a quick way to bundle up previous responses without extra boilerplate. Each flatMap step will wrap the prior response(s) along with the new one:

// Assuming you have a disposeBag defined somewhere
let disposeBag = DisposeBag()

getObservable1()
    // First flatMap: Pair API1 response with API2 response
    .flatMap { api1Response -> Observable<(API1Response, API2Response)> in
        getObservable2(param: api1Response)
            .map { api2Response in (api1Response, api2Response) }
    }
    // Second flatMap: Add API3 response to the tuple
    .flatMap { (api1, api2) -> Observable<(API1Response, API2Response, API3Response)> in
        getObservable3(param: api2)
            .map { api3Response in (api1, api2, api3Response) }
    }
    .subscribe(onNext: { api1, api2, api3 in
        // Now you have access to all three responses!
        print("Got API1 response: \(api1)")
        print("Got API2 response: \(api2)")
        print("Got API3 response: \(api3)")
    })
    .disposed(by: disposeBag)

This approach is perfect for short chains (3-4 steps max) because tuples stay readable. The downside is that tuples get unwieldy if you need to add more steps later.

Option 2: Use a Custom Struct for Better Readability

If you anticipate extending the chain or want cleaner code, define a struct to encapsulate all your responses. This makes the code more maintainable and self-documenting:

First, create the struct:

struct CombinedAPIResponses {
    let api1: API1Response
    let api2: API2Response
    let api3: API3Response
}

Then adjust your Rx chain to populate this struct:

let disposeBag = DisposeBag()

getObservable1()
    .flatMap { api1 in
        getObservable2(param: api1)
            .map { api2 in (api1, api2) }
    }
    .flatMap { (api1, api2) in
        getObservable3(param: api2)
            .map { api3 in CombinedAPIResponses(api1: api1, api2: api2, api3: api3) }
    }
    .subscribe(onNext: { combinedResponses in
        // Access responses via the struct's properties
        print("API1 data: \(combinedResponses.api1)")
        print("API2 data: \(combinedResponses.api2)")
        print("API3 data: \(combinedResponses.api3)")
    })
    .disposed(by: disposeBag)

Structs shine here because they give you named properties (no guessing which tuple element is which) and are easy to extend if you add a getObservable4 later.

Key Notes

  • Both approaches preserve the dependent sequence flow: getObservable2 only runs after getObservable1 completes, and getObservable3 only runs after getObservable2 completes.
  • Avoid trying to use scan for this scenario—scan is for accumulating values from a sequence, but your chain relies on each step’s output to trigger the next request, which flatMap handles perfectly.

Hope this solves your problem! 😊

内容的提问来源于stack exchange,提问作者13thang08

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 06:53:50