为啥带有多个可观察对象的 RxSwift concat 似乎不起作用?

Posted

技术标签:

【中文标题】为啥带有多个可观察对象的 RxSwift concat 似乎不起作用?【英文标题】:Why RxSwift concat with multiple observables does not seem to work?为什么带有多个可观察对象的 RxSwift concat 似乎不起作用? 【发布时间】:2020-02-06 12:52:22 【问题描述】:

我的RxSwift 代码是,

func testOperators()

    let bag = DisposeBag()

    let observable1 = PublishSubject<String>()
    let observable2 = PublishSubject<String>()

    Observable.concat([observable1, observable2])
        .subscribe(onNext:  (value) in
            print(value)
        ).disposed(by: bag)

    observable1.on(.next("1"))
    observable1.on(.next("2"))

    observable2.on(.next("3"))
    observable2.on(.next("4"))

    observable1.on(.completed)
    observable2.on(.completed)

当前输出是,

1
2

我的预期输出是,

1
2
3
4

我缺少什么以及我可以添加/编辑什么以获得预期的输出?

【问题讨论】:

【参考方案1】:

您在 concat 订阅 observable2 之前发出“3”和“4”。 concat 尚未订阅 observable2,因为它正在等待 observable1 完成。当 concat 订阅 observable2 时,“3”和“4”事件已经消失了。

打个比方:假设您有两个人投球,而您有一个接球手。您已经告诉接球手接住第一个投掷者的所有球,然后切换到第二个投掷者。第一个投掷者向接球手投两个球,第二个投掷者向任何人投掷两个球,因为接球手正在等待看第一个投掷者是否会再投球。然后第一个投掷者告诉接球手他已经完成了投球。然后接球手开始观察第二个投掷者,后者说他也完成了。最后,接球手只接住了两个球。

如果您要将 observable2 转换为具有足够大缓冲区的 ReplaySubject,那么它将为每个订阅者重放它接收到的所有事件,您将获得所需的输出。

【讨论】:

【参考方案2】:
    let bag = DisposeBag()

    let observable1 = PublishSubject<String>()
    let observable2 = PublishSubject<String>()

    Observable.concat([observable1, observable2])
        .subscribe(onNext:  (value) in
            print(value)
        ).disposed(by: bag)

    observable1.on(.next("1"))
    observable1.on(.next("2"))
    observable1.on(.completed) //observable1 emission has been completed here.


    //so now observable2 emission will start here
    observable2.on(.next("3"))
    observable2.on(.next("4"))
    observable2.on(.completed) //observable2 emission has been completed here.

这会给你预期的输出,我希望这会有所帮助:)

【讨论】:

@sazzad-hissain-khan 使用此代码,它可以按照您的期望工作。

以上是关于为啥带有多个可观察对象的 RxSwift concat 似乎不起作用?的主要内容,如果未能解决你的问题,请参考以下文章

地图中的 RxSwift 多个可观察对象

RxSwift:嵌套可观察对象上的 FlatMap

等待多个可观察请求完成使用 RXSwift

RxSwift 可观察到的错误停止链 - 带有 Rx 的 Web 服务,如何恢复?

RxSwift:结合不同类型的可观察对象和映射结果

RxSwift 将可观察对象数组与对象数组结合