RXJava BehaviorSubject的异步初始化

6

Sketch App 结构

在我的Android应用中,我使用BehaviorSubject从数据提供程序获取数据并将其传递给UI和其他需要数据的服务。为了举例说明,我们假设这些是用户的消息。

每当触发数据(例如消息)的刷新时,数据提供程序将执行“长时间运行”(也称为“慢速”)网络调用以检索消息,并通过调用主体的onNext(data)操作将它们馈送到主题中,从而将更新“广播”到UI和其他订阅者。

这个方法很有效,但是我在主体的初始化方面遇到了问题,或者换句话说,我在应用程序启动时设置主体的初始值时遇到了问题。

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

以下是我在数据提供程序的初始化中所做的内容:

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

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

getDataFromNetwork() 返回网络调用结果的一个 Observable。

问题: 手动将刷新自网络的 observable 与 BehaviourSubject 进行连接,似乎有些不够优雅。有没有更好的方法来使用另一个 Observable 初始化一个 BehaviourSubject?

我想到了这样一种方式: BehaviorSubject.create(Observable obs) 或者在我的情况下是 BehaviourSubject.create(getDataFromNetwork()),它可以设置 subject,使其保持为空,直到 Observable 发出一些东西,然后将此东西“推送”给其订阅者。

1个回答

1
“感觉不对的是你在使用一个主题。在Rx中,一般建议尽可能少地使用主题,你会惊讶于不使用主题可以实现多少功能。”
“在你的情况下,应该简单地暴露一个可观察对象而不是主题:”
Observable<Data> cachedData = getDataFromNetwork().publish().replay(1);

我会用完全的 Rx 方式来处理你试图欺骗 BehaviorSubject 的问题。

如果你想要刷新查询,那么 switch 可能是你需要的操作符,例如假设 refreshObs 是一个在刷新时触发的可观察对象:

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

我该如何将更新的数据输入到“cachedData”可观察对象中? - Florian Barth
getDataFromNetwork()正在为它们“提供”数据,但也许你的问题是想要定时重新执行网络查询?如果是这样的话,你是在什么条件下执行这个操作的? - Gluck
转换+发出可观察的可观察对象......太棒了!谢谢! - Florian Barth
(回答您的问题,刷新是通过时间或用户交互触发的,但这只是将这些事件“管道化”到刷新观察器中,对吧?) - Florian Barth
是的,最终会返回一个初始值concat'ed,以确保任何观察者都会得到一个值,即使从未调用过刷新。 - Gluck
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接