![](/img/trans.png)
[英]Why does my RxJava Observable not emit or complete unless it's blocking?
[英]Why does my RxJava Observable emit only to the first consumer?
有人可以解释为什么下面的测试失败了吗?
public class ObservableTest {
@Test
public void badObservableUsedTwiceDoesNotEmitToSecondConsumer() {
// Any simpler observable makes the test pass
Observable<Integer> badObservable = Observable.just(1)
.zipWith(Observable.just(2), (one, two) -> Observable.just(3))
.flatMap(observable -> observable);
ObservableCalculator calc1 = new ObservableCalculator(badObservable);
ObservableCalculator calc2 = new ObservableCalculator(badObservable);
// zipping causes the failure
// Calling calculate().toBlocking().subscribe() on each calc passes
// Observable.from(listOfCalcs).flatMap(calc -> calc.calculate()) passes
Observable.zip(ImmutableList.of(calc1.calculate(), calc2.calculate()), results -> results)
.toBlocking()
.subscribe();
assertThat(calc1.hasCalculated).isTrue();
assertThat(calc2.hasCalculated).isTrue(); // this fails
}
private static class ObservableCalculator {
private final Observable<?> observable;
public boolean hasCalculated = false;
public ObservableCalculator(Observable<?> observable) {
this.observable = observable;
}
public Observable<Void> calculate() {
return observable.concatMap(o -> {
hasCalculated = true;
// returning Observable.just(null) makes the test pass
return Observable.empty();
});
}
}
}
我试图进一步简化可观察到的“坏”现象,但是找不到我可以删除的任何东西以使其更简单。
但是,我目前的理解是,它是一个Observable,无论它是如何构造的,都应该发出一个值然后完成。 然后,我们基于该Observable创建对象的两个类似实例,并在使用Observable的那些对象上调用方法,记下这样做的情况,然后返回Observable.empty()。
谁能解释为什么使用此可观察的方法导致测试失败 (使用更简单的可观察的方法导致测试通过)?
也可以通过串行调用calculate()。toBlocking()。subscribe()而不是使用zip来使测试通过,或者使compute返回Observable.just(null)。 这有一定道理,我(拉链不会订阅CALC2如果CALC1是空的,因为在这种情况下压缩不可能产生任何东西),但不是完整意义上的(我不明白为什么拉链不那样做的一个更简单的badObservable版本-无论输入如何,calculate()方法仍然返回空值。
如果您用某物压缩空源,则操作员将检测到它不再产生任何值,并取消订阅所有源。 涉及到zip和merge的混合,并且merge认真对待取消订阅:它根本不会发出值3,因此concatMap也不会为第二个源调用映射函数。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.