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)
.
之间区别的用户身上拯救出来
- Don't forward errors/completions events to the subject:
确实如此,但根据我们与初学者的经验,他们通常不会考虑这一点,甚至不知道可以考虑的可用方法。
- 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 观察数据更改时。
我正试图通过 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)
.
- Don't forward errors/completions events to the subject:
确实如此,但根据我们与初学者的经验,他们通常不会考虑这一点,甚至不知道可以考虑的可用方法。
- 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 观察数据更改时。