【问题标题】:PublishSubject does not work with firstOrError()PublishSubject 不适用于 firstOrError()
【发布时间】:2018-06-22 17:31:32
【问题描述】:

有人可以解释一下为什么PublishSubject 不能很好地与firstOrError() 合作吗?

我希望 firstOrError 在创建 PublishSubject 时返回 NoSuchElementException 而没有任何值。

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

@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)
}

【问题讨论】:

  • “测试二”有时间问题。因为您在订阅前使用了onNext(),所以您不会看到true 的值。
  • 很公平,你是对的,我会删除那个例子,原因只是误导,我主要关心空场景。另一个呢?
  • 在“测试一”中,publishSubject 永远不会完成,因此firstOrError() 无法正确决定任何事情。
  • 嗯没有多大意义..无论如何,如果是这样的话,实现同样事情的方法是什么?如果不存在则获取第一项或错误?

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


【解决方案1】:

短版:Flowable 不发射任何元素并完成,而PublishSubject 不发射任何元素且未完成

长版:

您假设PublishSubject.create&lt;Boolean&gt;() 等价于Flowable.empty&lt;Boolean&gt;()。但他们不是。

首先,让我们看看firstOrError() 的真正作用:

返回一个 Single,它只发出此 Observable 发出的第一个项目,如果此 Observable 为空,则发出 NoSuchElementException 信号。

所以你认为Flowable.empty&lt;Boolean&gt;() 有效,因为它是空的。 "empty" 是什么意思?

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

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

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

如果你想有空的PublishSubject,只需调用PublishSubject.empty&lt;Boolean&gt;()

【讨论】:

  • v2 PublishSubject 文档更详细。此外,PublishSubject.empty()不是PublishSubject,而是Observable,因为empty()Observable 上的静态方法,在所有子类上可见且不能被覆盖。
  • 感谢您对差异的详细解释,这真的很有帮助。所以说 firstOrError() 在 PublishSubject 调用 onComplete 或 onNext 之前永远不会工作是否正确?
  • 感谢@akarnokd,您的意见总是有价值的。我更新了文档的链接,奇怪的是“默认”文档(正如您可以从链接中假设的那样)适用于旧版本。我同意你在 empty() 上的观点,但你认为这有实际区别还是你只是想准确命名?
  • 我们在 1.x javadocs 中设置了规范链接,但搜索引擎在构建索引时不需要遵循它。因此,PublishSubject 首先出现 1.x 文档,而 2.x 只是第二个。对主题的这种静态方法存在混淆;有些人确实希望他们返回一个主题。
猜你喜欢
  • 2020-11-29
  • 1970-01-01
  • 1970-01-01
  • 2023-04-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多