Rx java 如何包装始终返回最后一个结果的冷可观察(ReactiveX/RxJava)+;允许刷新
我试图依靠反应式编程与许多订户共享http调用的结果。同时,我希望能够再次执行调用(刷新) 我从执行http调用的cold Observable开始,然后立即完成 我想把它包装起来,以获得一个类似这样的热观测:每个订阅者都应该在订阅时接收最后一个事件(如果有),以及在取消订阅之前接收其他所有事件。我应该有一种方法(在可观察的外部)触发刷新,从而在所有订阅者上触发一个新事件 详情如下: 我对http请求的构建有一个冷的可观察性,通过Rx java 如何包装始终返回最后一个结果的冷可观察(ReactiveX/RxJava)+;允许刷新,rx-java,reactivex,Rx Java,Reactivex,我试图依靠反应式编程与许多订户共享http调用的结果。同时,我希望能够再次执行调用(刷新) 我从执行http调用的cold Observable开始,然后立即完成 我想把它包装起来,以获得一个类似这样的热观测:每个订阅者都应该在订阅时接收最后一个事件(如果有),以及在取消订阅之前接收其他所有事件。我应该有一种方法(在可观察的外部)触发刷新,从而在所有订阅者上触发一个新事件 详情如下: 我对http请求的构建有一个冷的可观察性,通过2。为了完整起见,这是我的服务接口 @GET("/path") O
2
。为了完整起见,这是我的服务接口
@GET("/path")
Observable<MyData> httpCall();
从服务中,我可以看到:
Observable<MyData> coldObservable = service.httpCall();
这样,http调用在第一次对其执行subscribe()
,如果我多次订阅,所有人都将“连接”到相同的coldObservable
调用完成后,如果我再次调用subscribe()
,将不会发生任何事情,甚至不会回调completed
相反,我希望它接收最后一个事件
如果用户请求,我想强制刷新(重复http调用)。所有订阅者都应收到新的结果/错误
我想象这样的情况:
Observable<MyData> theSmartObservable = helperClass.getObservable();
// at some point later
helperClass.triggerRefresh();
Observable thesmart-Observable=helperClass.getObservable();
//后来某个时候
helperClass.triggerRefresh();
触发的刷新应在SmartObservable中产生一个新事件
我如何建立这样一个可观察的模型
我希望我能解释我自己,如果不是,请在评论中告诉我。子类化Observable很棘手。用主题作文作为“桥梁”应该更容易。差不多
public class HelperClass {
private Subscription bridgeSubscription;
private ReplaySubject<MyData> bridgeSubject;
private MyService service;
private Subscriber<MyData> mSubscriber = new Subscriber<MyData>() {
@Override
public void onCompleted() {
// To DO
}
@Override
public void onError(Throwable e) {
// TO DO
}
@Override
public void onNext(MyData d) {
bridgeSubject.onNext(d);
}
};
public HelperClass(MyService service) {
this.service = service;
bridgeSubject = ReplaySubject.create(1);
bridgeSubscription = this.service.httpCall().publish().autoConnect().subscribe(mSubscriber);
}
public Observable<MyData> getObservable() {
// Might not work too well to hide the observable identity
// return bridgeSubject.asObservable();
return bridgeSubject;
}
public void triggerRefresh() {
if (bridgeSubscription != null) {
bridgeSubscription.unsubscribe();
bridgeSubscription = null;
}
bridgeSubscription = service.httpCall().publish().autoConnect().subscribe(mSubscriber);
}
}
公共类帮助类{
私人认购;
私人重播主体;
私人MyService服务;
专用订户MSSubscriber=新订户(){
@凌驾
未完成的公共无效(){
//做
}
@凌驾
公共无效申报人(可丢弃的e){
//做
}
@凌驾
公共void onNext(MyData d){
bridgeSubject.onNext(d);
}
};
公共助手类(MyService服务){
服务=服务;
bridgeSubject=ReplaySubject.create(1);
bridgeSubscription=this.service.httpCall().publish().autoConnect().subscribe(MSSubscriber);
}
公共可观察的getObservable(){
//可能无法很好地隐藏可观察到的身份
//返回bridgeSubject.asObservable();
返回主题;
}
公共无效触发器刷新(){
如果(bridgeSubscription!=null){
bridgeSubscription.Unsubscripte();
bridgeSubscription=null;
}
bridgeSubscription=service.httpCall().publish().autoConnect().subscribe(MSSubscriber);
}
}
您可以在hotObservable上使用.replay(1),以确保新订户始终从回答问题第一部分的observable.sweet中获取最后发出的项目。至于第二部分,如果您想强制刷新,只需创建另一组observable并订阅即可(在取消订阅您当前的观察对象后)。我不认为有任何需要做更为花哨的事情。这就是我不能/不想做的。有多个地方在使用数据,但或可能需要数据。刷新事件本身就是一个事件,正如我提到的,我仍在学习Rx,这是我第一次读到关于主题的内容。我做了一些研究,有人说“不要使用它们”,有人说“是的,比创造一个可观察的更好”。有人说(我倾向于听这一类)学习什么时候应该使用一个,什么时候不应该。我有了更好的知识后会回到这一点。考虑到你的要求,我怀疑你不使用主题也能达到你想要的行为。如果你想了解更多,Dávid Karnok(RxJava的主要贡献者之一)有一系列关于主题开始的博客帖子。我尝试了你的代码。我没有按照我希望的方式工作。当我调用triggerReresh时,http调用再次执行,但没有订阅该bridgeSubject的可观察对象接收事件。我进行了编辑,直接返回bridgeSubject,而不是试图隐藏其作为Su的身份订阅服务器是否在调用triggerRefresh之前收到事件?
Observable<MyData> theSmartObservable = helperClass.getObservable();
// at some point later
helperClass.triggerRefresh();
public class HelperClass {
private Subscription bridgeSubscription;
private ReplaySubject<MyData> bridgeSubject;
private MyService service;
private Subscriber<MyData> mSubscriber = new Subscriber<MyData>() {
@Override
public void onCompleted() {
// To DO
}
@Override
public void onError(Throwable e) {
// TO DO
}
@Override
public void onNext(MyData d) {
bridgeSubject.onNext(d);
}
};
public HelperClass(MyService service) {
this.service = service;
bridgeSubject = ReplaySubject.create(1);
bridgeSubscription = this.service.httpCall().publish().autoConnect().subscribe(mSubscriber);
}
public Observable<MyData> getObservable() {
// Might not work too well to hide the observable identity
// return bridgeSubject.asObservable();
return bridgeSubject;
}
public void triggerRefresh() {
if (bridgeSubscription != null) {
bridgeSubscription.unsubscribe();
bridgeSubscription = null;
}
bridgeSubscription = service.httpCall().publish().autoConnect().subscribe(mSubscriber);
}
}