Android PublishSubject不适用于firstOrError()

Android PublishSubject不适用于firstOrError(),android,rx-java,rx-java2,rx-kotlin,Android,Rx Java,Rx Java2,Rx Kotlin,有人能解释一下为什么PublishSubject不能很好地与firstOrError()配合使用吗 当创建的PublishSubject没有任何值时,我希望firstOrError返回一个NoTouchElementException 为了更好地解释问题,我编写了一些测试: @Test fun `test one`() { // THIS TEST FAILS val publishSubject = PublishSubject.create<Boolean>()

有人能解释一下为什么
PublishSubject
不能很好地与
firstOrError()配合使用吗

当创建的
PublishSubject
没有任何值时,我希望
firstOrError
返回一个
NoTouchElementException

为了更好地解释问题,我编写了一些测试:

@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)
}
@测试
有趣的‘测试一’(){
//这个测试失败了
val publishSubject=publishSubject.create()
val testSubscriber=publishSubject
//.toFlowable(BackpressureStrategy.LATEST)//有或没有这个没有任何区别
.firstOrError()
.test()
测试订户
.assertNotComplete()
.assertError(NoSuchElementException::class.java)
}
@试验
乐趣`测试二'(){
//这个测试通过了
val flowable=flowable.empty()
val testSubscriber=可流动
.firstOrError()
.test()
测试订户
.assertNotComplete()
.assertError(NoSuchElementException::class.java)
}

简短版本:
可流动
不发出元素并完成,而
PublishSubject
不发出元素并完成

长版本:

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

首先,让我们看看真正的作用是什么:

返回仅发出此可观测项发出的第一个项的单个项,或者如果此可观测项为空,则发出NoTouchElementException信号

因此,您可以理解,
Flowable.empty()
可以工作,因为它是空的。这是什么意思

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

我强调了重要的片段
Flowable.empty()
调用
onComplete
,而
PublishSubject.create()
只创建
Subject
,等待调用他或订阅者的
onNext()

所以
Flowable.empty()
是空的,但是
PublishSubject.create()
不是空的它不会调用
onComplete
查看以获取更多信息


如果您想使用空的
PublishSubject
,只需调用
PublishSubject.empty()

“测试二”有计时问题。因为您在订阅之前使用了
onNext()
,所以不会看到值
true
。公平地说,您是对的,我将删除该示例,因为这只是误导,我主要关心的是空场景。另一个呢?在“测试一”中,
publishSubject
从未完成,因此
firstOrError()
无法正确决定任何事情。Mmm没有多大意义。。无论如何,如果是这样的话,实现同样目标的方法是什么?获取第一项或错误(如果不存在)?v2文档更详细。此外,
PublishSubject.empty()
不是
PublishSubject
而是一个
可观察的
,因为
empty()
是一个在所有子类上可见的
可观察的
静态方法,不能被重写。感谢您对差异的详细解释,这真的很有帮助。那么,在PublishSubject调用onComplete或onNext之前,firstOrError()永远不会工作,这是正确的吗?谢谢@akarnokd,您的输入总是有价值的。我更新了链接到文档,奇怪的是“默认”文档(你可以从链接中假设)是针对旧版本的。我同意你关于
empty()
的观点,但你认为这有实际意义吗?还是你只是想精确地命名?我们在1.x javadocs中设置了规范链接,但搜索引擎在构建索引时不需要遵循它。因此,PublishSubject首先显示1.x文档,2.x只是第二个。在受试者身上对这种静态方法存在混淆;有些人真的期望他们返回一个主题。