Rx java2 RxJava中继vs主题

Rx java2 RxJava中继vs主题,rx-java2,Rx Java2,我试图理解Jake Warthon的图书馆的目的: 基本上:一个主题,除了不能调用onComplete或 一个错误。主体是有状态的,具有破坏性:当他们收到 一旦完成或出错,它们就不再可用于移动数据 我明白了,这是一个有效的用例,但是仅仅使用现有的主题似乎很容易实现上面的内容 1.不要将错误/完成事件转发给主题: `observable.subscribe({ subject.onNext(it) }, { log error / throw exception },{ ... })` 2.不

我试图理解Jake Warthon的图书馆的目的:

基本上:一个主题,除了不能调用onComplete或 一个错误。主体是有状态的,具有破坏性:当他们收到 一旦完成或出错,它们就不再可用于移动数据

我明白了,这是一个有效的用例,但是仅仅使用现有的主题似乎很容易实现上面的内容

1.不要将
错误
/
完成
事件转发给主题:

`observable.subscribe({ subject.onNext(it) }, { log error / throw exception },{ ... })`
2.不要暴露主题,而是让你的方法签名返回一个可观察的

fun():可观察的{return subject}

很明显,我在这里遗漏了一些东西,我对这是什么很好奇

class MyPublishRelay<I> : Consumer<I> {

    private val subject: Subject<I> = PublishSubject.create<I>()

    override fun accept(intent: I) = subject.onNext(intent)

    fun subscribe(): Disposable = subject.subscribe()
    fun subscribe(c: Consumer<in I>): Disposable = subject.subscribe(c)
    //.. OTHER SUBSCRIBE OVERLOADS
}
class MyPublishRelay:消费者{
private val subject:subject=PublishSubject.create()
覆盖乐趣接受(意图:I)=subject.onNext(意图)
乐趣订阅():一次性=主题。订阅()
乐趣订阅(c:消费者):一次性=主题。订阅(c)
//…其他订阅重载
}

subscribe
有过载,通常,人们习惯于
订阅(消费者)
过载。然后他们使用主题,然后突然调用
onComplete
。RxRelay将用户从他们自己手中解救出来,他们不考虑
subscribe(消费者)
subscribe(观察者)
之间的区别

  • 不要将错误/完成事件转发给主题:
  • 确实,但是根据我们和初学者的经验,他们通常不考虑这个问题,甚至不知道可用的方法。

  • 不要暴露主题,而是让你的方法签名返回一个可观察的

  • 如果您需要一种将项目发送到主题中的方法,那么这是行不通的。目的是使用主题执行项目多播,有时从另一个
    可见的
    。如果您通过
    主题
    完全控制排放,您应该有礼貌地不调用
    onComplete
    ,也不让其他任何操作进行。

    如果您使用主题,则执行
    主题。getValue
    将始终抛出有关空安全的错误。所以你必须在代码中的任何地方都放上“?或!!”,即使你知道它不能为空

    public T getValue() {
        Object o = value.get();
        if (NotificationLite.isComplete(o) || NotificationLite.isError(o)) {
            return null;
        }
        return NotificationLite.getValue(o);
    }
    
    受试者的开销要大得多,因为他们必须跟踪和处理数据 终端事件状态。除了订阅之外,中继是无状态的 管理层

    -杰克·沃顿

    (这是从GitHub上打开的问题OP中得出的,认为这是一个更正确的答案,并希望在此处“转发”给其他人看。)

    此外:


    在某些情况下,您无法控制可观察的
    数据库中的数据流,例如使用
    Room
    数据库观察数据库表中的数据更改。

    谢谢akarnokd,很高兴知道我没有遗漏任何内容:)关于#2如果您将主题放在包装类中,您可以有一个方法accept(item){subject.omNext(项目)}。主题仍然是一个私人领域。你确定这是唯一的原因吗?。创建一个全新的库只是为了避免初学者的错误似乎是一种过激的行为。那么将它导入到你的项目中也是吗?因为内部结构与标准主题基本相同,并且删除终端事件处理不是一个重要的问题无论哪一个,我们都会赢,这就是我写的。是的!我在阅读了你的答案后开始了这一期:)谢谢