【问题标题】:RxJava - Transform a cold observable to hot observableRxJava - 将冷可观察对象转换为热可观察对象
【发布时间】:2022-02-02 03:22:44
【问题描述】:

我要解决的问题

我正在构建一种 MVP(或您所称的任何名称),其中视图可以订阅和取消订阅相同的模型。

一开始,视图订阅模型。模型是空的,视图什么也不显示。 调用方法时(例如,当用户单击时),会通过网络发出请求。结果将填充模型,该模型将通知视图更改。

如果另一个视图订阅,它应该被通知模型当前值,而不需要通过网络进行任何调用。 如果在请求进行时所有视图都取消订阅,模型仍将被填充,以便另一个视图可以

我的尝试

我使用RetrofitRxJava2 通过网络发出请求,这提供了一个冷Observable

对于模型,我想构建一个热门的Observable,它将最后发出的项目返回给任何新订阅者。如何让热的 observable 从冷的 Observable 中获取其发射的项目?

到目前为止,我可以通过BehaviourSubject 实现这一点:

// The same model is provided to all views through a getter
BehaviorSubject<User> model = BehaviorSubject.create();

// Make request
Observable<User> resource = getResourceOverNetwork(3);
resource.subscribe(new Consumer<User>() {
    @Override
    public void accept(@NonNull User user) throws Exception {
        model.onNext(user);
    }
});

这个解决方案感觉不对,因为我必须手动将事件从冷的Observable 转发到BehaviourSubject

【问题讨论】:

  • 如果你只想让你的改造结果成为一个热门的可观察的。您可以使用replay(1).autoConnect
  • 使用replay(1).autoConnect(),我应该如何通过网络发出新请求,使用新参数,以便更新模型?
  • @LaureC。有两种方法:使用主题进行中继,以便您将操作发布到主题和模型订阅该主题并发出请求。或者使用发射器创建可观察对象。然而,发射器可能不适合 MVP 模式,但适用于 RxPM。
  • 很多方案其实都用到了subject,你可以简单的resource.subscribe(model)
  • @Lamorak,我忘了Subject 也是Observer,谢谢。但是在我的情况下它不起作用,因为resource 在发出第一个值后完成,使model 也完成。再次发出请求不会使 model 在完成时发出项目。

标签: rx-java rx-java2


【解决方案1】:

感谢你们的 cmets,我可以通过 RxRelay 成功实现我所需要的。

创建模型:

// The same model is provided to all views through a getter
BehaviorRelay<User> model = BehaviorRelay.create();
    
model.subscribe(view);

随时提出请求:

// Make request
Observable<User> resource = getResourceOverNetwork(3);
resource.subscribe(model);
    
// Make a new request
getResourceOverNetwork(4).subscribe(model);

现在更容易,也更干净。非常感谢!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-06
    • 1970-01-01
    相关资源
    最近更新 更多