RxJava 中继与主题

RxJava Relay vs Subjects

我正试图通过 Jake Warthon 了解这个库的用途: https://github.com/JakeWharton/RxRelay

Basically: A Subject except without the ability to call onComplete or onError. Subjects are stateful in a damaging way: when they receive an onComplete or onError they no longer become usable for moving data.

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

1.不要转发errors/completions事件给主题:

`observable.subscribe({ subject.onNext(it) }, { log error / throw exception },{ ... })`

2. 不要暴露主题,让你的方法签名 return 成为可观察的。

fun(): Observable<> { 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
}

subscribe 有过载,通常人们会习惯 subscribe(Consumer) 过载。然后他们使用主题,突然 onComplete 也被调用。 RxRelay 将用户从不考虑 subscribe(Consumer)subscribe(Observer).

之间区别的用户身上拯救出来
  1. Don't forward errors/completions events to the subject:

确实如此,但根据我们与初学者的经验,他们通常不会考虑这一点,甚至不知道可以考虑的可用方法。

  1. Don't expose the subject, make your method signature return an observable instead.

如果您需要一种方法将项目发送到主题中,这将不起作用。目的是使用主题执行项目多播,有时来自另一个 Observable。如果您通过 Subject 完全控制排放,您应该有礼貌地不调用 onComplete 并且也不要让任何其他事情这样做。

如果你使用 Subjects,执行 subjects.getValue 总是会抛出关于 null safety 的错误。所以你必须输入“?或!!”在您的代码中的任何地方,即使您知道它不可为空。

public T getValue() {
    Object o = value.get();
    if (NotificationLite.isComplete(o) || NotificationLite.isError(o)) {
        return null;
    }
    return NotificationLite.getValue(o);
}

Subjects have far more overhead because they have to track and handle terminal event states. Relays are stateless aside from subscription management.

- Jake Wharton

(这是来自 OP 在 GitHub 上打开的问题,并且认为这是一个更正确的答案,并想在这里“转发”它以供其他人查看。https://github.com/JakeWharton/RxRelay/issues/30

除了

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