将publish()
与observeOn
和subscribeOn
结合使用时,我发现了一些奇怪的行为。请看下面的例子。
代码:
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();
}
}
).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
条件!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();
输出:
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
请帮助我了解条件!subscriber.isUnsubscribed()
成为true
的原因。
PS。我了解如果我想检查!subscriber.isUnsubscribed()
,我应该使用.publish().refCount()
代替connect()
。我的目标是了解当前的行为。
答案 0 :(得分:3)
publish()
通过消耗源流直到完成(这里从未发生过)来对0个订阅者做出反应。因此,一旦您使用唯一的subscribe()获取10,源将永远保持运行,或直到您在connect()调用返回的unsubscribe
上调用Subscription
。
在第二种情况下,你得到!subscriber.isUnsubscribed()为true,因为你溢出了observeOn或发布的内部队列,而整个链都以MissingBackpressureException
消亡,触发了最终到达你的Observable的取消订阅。
你需要的是share()而不仅仅是publish()所以如果所有订阅者都离开你的源会被终止,但请注意,由于你的Observable不尊重背压,你仍然倾向于{{1} }。
通常,我建议首先查看标准运算符和Observable工厂,而不是滚动Observable,或查看MissingBackpressureException
及其javadoc中的示例,以了解如何实现背压感知自定义Observable。