为什么Observable.empty()不在onComplete()下游传播?

时间:2018-08-26 08:12:39

标签: rx-java rx-java2

RxJava Observable.empty()的{​​{3}}告诉:

  

创建一个不发射任何物品但正常终止的Observable

“正常终止”表示呼叫onComplete()

因此,在下游观察者中,我希望收到onComplete()。但这不会发生。

任何想法为何?在这种情况下,“正常终止”是否意味着其他含义?

这是示例代码:

Observable.just(2, 3, 0, 15, 12, 1)
            .flatMap(new Function<Integer, ObservableSource<String>>() {
                @Override
                public ObservableSource<String> apply(Integer integer) throws Exception {
                    if (integer == 0) {
                        return Observable.empty();
                    } else {
                        return Observable.just("Value: " + integer);
                    }
                }
            })
            .subscribe(observer);

observer未收到onComplete()

2 个答案:

答案 0 :(得分:1)

您的代码可能还有其他问题,因为可观察到的空会调用onComplete。

这里有一个简单的测试来检查这一点(以kotlin格式):

class RxObservableTest {

    @Test
    fun checkObservable() {
        Observable.empty<Int>()
                .doOnComplete { println("Received OnComplete") }
                .test()
                .assertComplete()
    }
}

输出为:

Connected to the target VM, address: '127.0.0.1:63929', transport: 'socket'
Received OnComplete
Disconnected from the target VM, address: '127.0.0.1:63929', transport: 'socket'

Process finished with exit code 0

更新

所以我想我现在已经了解您的问题了。

您希望在每个Observable完成后收到onCompleted,但这不是RxJava的工作方式。 来自观察者documentation

  

并且调用模式必须遵守以下协议:

     

onSubscribe onNext *(onError | onComplete)?

这意味着每个Observer将收到不超过一个onComplete事件,此后in将不会接收任何事件。在这种情况下,Observable中的所有flatMap个都完成之后就接收到它。在您的情况下,最后一个发出1,并且您看到的正是输出。

如果您想收到Observable.empty()的完成通知,则可以考虑提供比Integer更复杂的数据

答案 1 :(得分:1)

Observable类型为例,flatMap的实际作用是:

  1. 从上游的每个发射映射到Observable<T>,这将整个流有效地转换为Observable<Observable<T>>。让您摆脱类似“回调地狱”的语法,然后...

  2. 展平,它们会简单地流入Observable<T>

(出于这个原因,我一直以为flatMap这个名字似乎倒过来了)

因此,使用您的示例输入, map 操作将产生:

2  --> Observable(2)
3  --> Observable(3) 
0  --> Observable()
15 --> Observable(15)
12 --> Observable(12)
1  --> Observable(1)

此时,流现在为Observable<Observable<Integer>>

随后展平内部Observable<Integer>排放产生的流实际上与以下内容相同:

Observable(2, 3, 15, 12, 1)

...由于Observable.empty()不产生任何结果。

据我所知,您当时认为0发射会有效终止整个流,但这不是flatMap的工作方式。但是,如果这是您想要的行为,那么我认为switch*运算符的某些变体可能更适合您。

希望对您有所帮助!