RxJava-缓存直到排放闲置一段时间?

RxJava-缓存直到排放闲置一段时间?,java,reactive-programming,rx-java,Java,Reactive Programming,Rx Java,我经常遇到一种模式,我不太确定如何有效地绕过它 基本上,如果我有一个Observable持有一个昂贵的物品T,我不想在每次有人使用它时重新构建这个T物品,或者将它映射到1000个不同的其他可观察物品,这将导致它被构建1000次 因此,我开始使用replay()将其缓存一段时间,但理想情况下,我希望它在排放闲置一段时间后清除缓存 是否有一个操作员或一些变压器可以实现这一点 public final class ActionManager { private final Observabl

我经常遇到一种模式,我不太确定如何有效地绕过它

基本上,如果我有一个
Observable
持有一个昂贵的物品
T
,我不想在每次有人使用它时重新构建这个
T
物品,或者将它映射到1000个不同的其他可观察物品,这将导致它被构建1000次

因此,我开始使用
replay()
将其缓存一段时间,但理想情况下,我希望它在排放闲置一段时间后清除缓存

是否有一个操作员或一些变压器可以实现这一点

public final class ActionManager {

    private final Observable<ImmutableList<Action>> actionMap;

    private ActionManager() { 
        this.actionMap = Observable.defer(() -> buildExpensiveList()).replay(10, TimeUnit.SECONDS).autoConnect();
    }

    //this method could get called thousands of times
    //I don't want to rebuild the map for every call

    public Observable<Action> forItem(Item item) { 
        actionMap.map(l -> //get Action for item);
    }


}
公共最终类ActionManager{
私人最终可观察行动图;
私有ActionManager(){
this.actionMap=Observable.defer(()->buildExpensiveList()).replay(10,TimeUnit.SECONDS).autoConnect();
}
//此方法可能会被调用数千次
//我不想为每次通话重建地图
公共可观测项(项){
map(l->//获取项目的操作);
}
}
更新

尝试将其实现到Transformer/Operator组合中。我有什么地方做错了吗

   public static <T> Transformer<T,T> recacheOnIdle(long time, TimeUnit timeUnit) { 

        return obs -> obs.timeout(time, timeUnit).lift(new Operator<T,T>() {

            private volatile T cachedItem;
            private volatile boolean isCurrent = false;

            @Override
            public Subscriber<? super T> call(Subscriber<? super T> s) {
                return new Subscriber<T>(s) {
                    @Override
                    public void onCompleted() {
                         if(!s.isUnsubscribed()) {
                              s.onCompleted();
                         }
                    }
                    @Override
                    public void onError(Throwable e) {
                        if(!s.isUnsubscribed()) {
                            if (e instanceof TimeoutException) { 
                                isCurrent = false;
                                cachedItem = null;
                            } else { 
                                s.onError(e);
                            }
                        }
                    }

                    @Override
                    public void onNext(T t) {
                        if(!s.isUnsubscribed()) { 
                            if (!isCurrent) { 
                                cachedItem = t;
                            }
                            s.onNext(cachedItem);
                        }
                    } 
                };
            }

        });
    }
public static Transformer recachonidle(长时间,时间单位){
返回obs->obs.timeout(时间,时间单位).lift(新操作员(){
私人易变性T纪念物;
私有易失性布尔值isCurrent=false;
@凌驾

公共订户您可以使用和(用于容纳和同步多个订户):

镜像可观察的源,但如果特定时间段内没有任何发射项,则发出错误通知

这是通过重新缓存昂贵的项目来响应抛出的错误的方法。假设这是一种“罕见”的情况:

//如果在3秒钟内没有排放-将调用onError
observableWithCache.timeout(3000,TimeUnit.ms).subscribe(新订户(){
未完成的公共无效(){
}
公共作废申报人(可丢弃arg0){
doClearCache();//请确保使用超时重新订阅
}
public void onNext(SomeObject项){
System.out.println(“Got item:+item);//您可以忽略这个
}
});
请注意,
onError
不会取消原始可观测值,如图所示:


但是你可以对一段时间内没有发射做出反应。

看看我为rxjava2创建的这个。它是一个自定义转换器,将在一段时间内保留缓存值。

在时间过去后不会重播清除缓存吗?是的,但我想在一段时间后清除缓存泰,不是一个固定窗口。太棒了。我正试图实现一个转换器/操作符组合来实现这一点,我更新了上面的帖子。我对操作符没有经验,当错误出现时,有些东西不太管用。
// if no emissions are made for a period of 3 seconds - will call onError
observableWithCache.timeout(3000, TimeUnit.MILLISECONDS).subscribe(new Subscriber<SomeObject>() {

    public void onCompleted() {

    }

    public void onError(Throwable arg0) {
        doClearCache(); // make sure to re-subscribe with timeout
    }

    public void onNext(SomeObject item) {
        System.out.println("Got item: " + item); // you can ignore this
    }
});