RxJava:为什么订阅共享的可观察更改发出的项目

时间:2018-02-07 23:10:48

标签: rx-java reactive-programming rx-java2

我偶然发现了一些我无法解释的令人费解的行为。我从一个更大的rx链中提取了下面的例子,所以不要惊讶为什么我会这样做。我只想了解为什么会发生这种情况! :)

enum class Request {
    Request1,
    Request2
}


fun main(args: Array<String>) {
    val requestStream = PublishSubject.create<Request>()

    val stateChanges = requestStream.share()

    stateChanges
        .delaySubscription(requestStream)
        .subscribe({ println("received $it") })

    // Comment this and it changes the output!
    stateChanges.subscribe()

    requestStream.onNext(Request.Request1)
    requestStream.onNext(Request.Request2)
}

因此。如果您运行上面的程序,它将打印:

received Request1
received Request2

但是,如果你发表评论stateChanges.subscribe(),会突然Request1丢失并且只会打印出来:

received Request2
你可以解释一下吗? 另外我想知道是否有可能让上面的设置发出两个项目,即使没有额外的subscribe()

1 个答案:

答案 0 :(得分:3)

在正常情况下,share已经与requestStream相关联,由于delaySubscription(requestStream)shareObserver之前获得第二个requestStream发送Request1。因此,requestStream有两个Observer s,向第一个发送者发送Request1给另一个消费者Observer添加另一个share,因此,最终订阅者获得Request1。

在已注释的案例中,share尚未与requestStream相关联,因此requestStream只能通知delaySubscriptiondelaySubscription会触发share,然后订阅requestStream。但是,PublishSubject仅将项目发送到Observer的当前快照,并且在此期间无法看到其第一个onNext添加了新的Observer。因此,Request1未达到println

这个角落案例未由PublishSubject处理,因为它需要其onNext记住哪个Observer已收到当前项目,并在当前Observer的情况下继续重试1}}改变了。这增加了内存和时间开销。