繁体   English   中英

为什么我的RxJava Observable只发给第一个使用者?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM