Rx java rxJava。帮助了解发布和取消订阅的工作原理

Rx java rxJava。帮助了解发布和取消订阅的工作原理,rx-java,Rx Java,当将publish()与observeOn和subscribeOn结合使用时,我观察到奇怪的行为。请看下面的例子 代码: 条件!subscriber.isUnsubscribed()从未发生过。这完全没问题。当我添加observeOn(Schedulers.newThread())和subscribeOn(Schedulers.newThread())时,会发生奇怪的事情。看一看: ConnectableObservable<String> observable = Observab

当将
publish()
observeOn
subscribeOn
结合使用时,我观察到奇怪的行为。请看下面的例子

代码:

条件<代码>!subscriber.isUnsubscribed()从未发生过。这完全没问题。当我添加
observeOn(Schedulers.newThread())
subscribeOn(Schedulers.newThread())
时,会发生奇怪的事情。看一看:

ConnectableObservable<String> observable = Observable.create(
    new Observable.OnSubscribe<String>() {
        @Override
        public void call(Subscriber<? super String> subscriber) {
            int i=0;
            Log.d("testTag:", "start call");
            while (!subscriber.isUnsubscribed()) {
                subscriber.onNext("item "+i);
                i++;
            }
            Log.d("testTag:", "completed");
            subscriber.onCompleted();
        }
    }
)
.observeOn(Schedulers.newThread())
.subscribeOn(Schedulers.newThread())
.publish();

observable
    .take(10)
    .subscribe(
        new Action1<String>() {
            @Override
            public void call(String s) {
                Log.d("testTag:", "item received 1 : " + String.valueOf(s));
            }
        });

observable.connect();
请帮助我理解为什么条件
!subscriber.isUnsubscribed()
变为
true

注:我明白如果我想检查
!subscriber.isUnsubscribed()
我应该使用
.publish().refCount()
而不是
connect()
。我的目标是了解当前行为。

publish()
通过使用源流直到完成来对0订阅者做出反应(在这里永远不会发生)。因此,一旦您使用sole subscribe()获取10,源代码将一直运行,或者直到您对connect()调用返回的
Subscription
调用
unsubscribe

在第二种情况下,你得到了!subscriber.isUnsubscribed()为true,因为您使observeOn或publish的内部队列溢出,整个链因
MissingBackpressureException
而终止,这将触发最终到达您的observeable的取消订阅

您需要的是share()而不是publish(),这样,如果所有订阅者都离开了,您的源代码就会终止,但请注意,由于您的可观察对象不考虑背压,因此您仍然容易
丢失背压异常

通常,我建议首先查看标准运算符和可观察工厂,而不是滚动您的可观察对象,或者查看
AbstractOnSubscribe
及其javadoc中的示例,以了解如何实现可感知背压的自定义可观察对象。

很遗憾:(我过滤了日志,没有看到
丢失背压异常
:(很抱歉问了这么愚蠢的问题。谢谢你抽出时间!
start call
item received 1 : item 0
item received 1 : item 1
item received 1 : item 2
item received 1 : item 3
item received 1 : item 4
item received 1 : item 5
item received 1 : item 6
item received 1 : item 7
item received 1 : item 8
item received 1 : item 9
ConnectableObservable<String> observable = Observable.create(
    new Observable.OnSubscribe<String>() {
        @Override
        public void call(Subscriber<? super String> subscriber) {
            int i=0;
            Log.d("testTag:", "start call");
            while (!subscriber.isUnsubscribed()) {
                subscriber.onNext("item "+i);
                i++;
            }
            Log.d("testTag:", "completed");
            subscriber.onCompleted();
        }
    }
)
.observeOn(Schedulers.newThread())
.subscribeOn(Schedulers.newThread())
.publish();

observable
    .take(10)
    .subscribe(
        new Action1<String>() {
            @Override
            public void call(String s) {
                Log.d("testTag:", "item received 1 : " + String.valueOf(s));
            }
        });

observable.connect();
start call
item received 1 : item 0
item received 1 : item 1
item received 1 : item 2
item received 1 : item 3
item received 1 : item 4
item received 1 : item 5
item received 1 : item 6
item received 1 : item 7
item received 1 : item 8
item received 1 : item 9
completed