Rx java 如何包装始终返回最后一个结果的冷可观察(ReactiveX/RxJava)+;允许刷新

Rx java 如何包装始终返回最后一个结果的冷可观察(ReactiveX/RxJava)+;允许刷新,rx-java,reactivex,Rx Java,Reactivex,我试图依靠反应式编程与许多订户共享http调用的结果。同时,我希望能够再次执行调用(刷新) 我从执行http调用的cold Observable开始,然后立即完成 我想把它包装起来,以获得一个类似这样的热观测:每个订阅者都应该在订阅时接收最后一个事件(如果有),以及在取消订阅之前接收其他所有事件。我应该有一种方法(在可观察的外部)触发刷新,从而在所有订阅者上触发一个新事件 详情如下: 我对http请求的构建有一个冷的可观察性,通过2。为了完整起见,这是我的服务接口 @GET("/path") O

我试图依靠反应式编程与许多订户共享http调用的结果。同时,我希望能够再次执行调用(刷新)

我从执行http调用的cold Observable开始,然后立即完成

我想把它包装起来,以获得一个类似这样的热观测:每个订阅者都应该在订阅时接收最后一个事件(如果有),以及在取消订阅之前接收其他所有事件。我应该有一种方法(在可观察的外部)触发刷新,从而在所有订阅者上触发一个新事件

详情如下: 我对http请求的构建有一个冷的可观察性,通过
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);
    }
}