RXJava BehaviorSubject 的 Asnyc 初始化

Asnyc Initialisation of RXJava BehaviorSubject

在我的 Android 应用程序中,我使用来自数据提供商的 BehaviourSubject "to get data" 到我的 UI 和其他需要数据的服务。举个例子,我们假设这些是我们用户的消息。

每当触发数据(例如消息)的刷新时,数据提供者将进行 "long running"(又名 "slow")网络调用以检索消息并通过调用将它们提供给主题主题的 onNext(data) 操作,因此 "broadcasting" 对 UI 和其他订阅者的更新。

这很好用,但我在初始化主题时遇到问题,或者换句话说,在应用启动时设置主题的初始值。

我知道我可以通过 BehaviorSubject.create(initialValue) 设置初始值,但是由于 initialValue 是网络调用的结果,这会阻止初始化主题。

我目前在我的数据提供商的 init 中执行以下操作:

BehaviorSubject<Data> subject = BehaviorSubject.create();

getDataFromNetwork().subscribe(data -> subject.onNext(data));

其中 getDataFromNetwork() returns 网络调用结果的 Observable。

问题: 上面将手动从网络刷新的 observable 连接到 BehaviourSubject 的构造感觉 错误 / 不优雅。有没有更好的方法用另一个 Observable 初始化一个 BehaviourSubject?

我在想类似的事情: BehaviorSubject.create(Observable obs) 或在我的例子中 BehaviourSubject.create(getDataFromNetwork()) 将设置主题,将其留空直到 Observable 发出一些东西,然后 "pushes" 将这个东西发送给它的订阅者。

感觉 错误的是您使用的是主题。在 Rx 中,一般建议不要使用主题(尽可能多),你会惊讶于你能达到多少 w/o 它们。

在您的情况下,您应该简单地公开一个可观察对象而不是主题:

Observable<Data> cachedData = getDataFromNetwork().publish().replay(1);

它的工作方式与您试图欺骗 BehaviorSubject 的方式相同,但完全是 Rx。

如果您想刷新查询,那么 switch 就是您可能需要的运算符,例如假设 refreshObs 是一个在刷新时滴答作响的可观察对象:

Observable<Data> cachedData = refreshObs.map(t -> getDataFromNetwork())
                                        .switchOnNext()
                                        .publish().replay(1);