PublishSubject不适用于firstOrError()

时间:2018-06-22 17:31:33

标签: android rx-java rx-java2 rx-kotlin

有人可以向我解释为什么PublishSubjectfirstOrError()上不能很好地工作吗?

我期望firstOrError在创建NoSuchElementException时没有任何值的情况下返回PublishSubject

我写了一些测试以更好地解释问题:

@Test
fun `test one`() {
    // THIS TEST FAILS
    val publishSubject = PublishSubject.create<Boolean>()

    val testSubscriber = publishSubject
        // .toFlowable(BackpressureStrategy.LATEST) // With or without this doesn't make any difference
        .firstOrError()
        .test()

    testSubscriber
        .assertNotComplete()
        .assertError(NoSuchElementException::class.java)
}

@Test
fun `test two`() {
    // THIS TEST PASSES
    val flowable = Flowable.empty<Boolean>()

    val testSubscriber = flowable
        .firstOrError()
        .test()

    testSubscriber
        .assertNotComplete()
        .assertError(NoSuchElementException::class.java)
}

1 个答案:

答案 0 :(得分:3)

简短版本: Flowable不发出任何元素且不完整,而PublishSubject不发出任何元素且不完整

长版:

您假设PublishSubject.create<Boolean>()等同于Flowable.empty<Boolean>()。但事实并非如此。

首先,让我们看看firstOrError()的实际作用:

  

返回一个Single,该Single仅发出此Observable发出的第一项内容;如果此Observable为空,则发出NoSuchElementException信号。

因此,Flowable.empty<Boolean>()有效是有道理的,因为它是空的。 "empty"是什么意思?

  

返回不向订阅者发送任何项目的Flowable,并立即调用其onComplete方法。

我强调了重要的片段。 Flowable.empty()呼叫onComplete,而PublishSubject.create()仅创建Subject,它等待在他或订户上呼叫onNext()

因此Flowable.empty()为空,但PublishSubject.create()不为空。 它不会调用onComplete有关更多信息,请参见PublishSubject docs

如果您想使用空的PublishSubject,只需致电PublishSubject.empty<Boolean>()