java - RxJava : Read from cache until timestamp is expired

标签 java android rx-java reactive-programming

我有以下场景:我有一个我的应用程序感兴趣的名为 Foo 的对象。这个 Foo 对象来自远程服务,我想在本地缓存此实例并继续使用它,直到经过一定时间。

到目前为止,我已经尝试创建一个 FooState 类,其中包含 Foo 的实例以及指示 Foo 时间的时间戳以毫秒为单位获取:

public class FooState {

    private Foo foo;
    private long timestamp;

    /* Constructor and getters */

}

现在,到目前为止,我已经想出了这段使用 concat 的代码:

public Observable<Foo> foo() {
    return Observable.concat(local(), remote())
               .takeFirst(fooState -> fooState.getTimestamp() >= System.currentTimeMillis())
               .map(fooState -> fooState.getFoo())
               .defaultIfEmpty(new Foo());

}

private Observable<FooState> local() {
    return Observable.just(cache.hasFooState() ? cache.getFooState() : new FooState(null, 0));
}

private Observable<FooState> remote() {
    return api.getFoo()
              .map(foo -> new FooState(foo, System.currentTimeMillis() + ONE_DAY_MILLIS)
              .doOnNext(fooState -> {
                   cache.save(fooState);
              });
}

基本上,如果有缓存值,只要时间戳未过期,我就想使用它。如果时间戳过期或者没有缓存值,我想从远程服务中获取并缓存结果。

有没有更简洁的方法来实现这个用例?我是 RxJava 的新手,我想知道是否有任何 Rx 大师知道处理这种情况的更好方法。

最佳答案

您还可以使用内置的 .timestamp() 运算符和 Timestamped 类。

    BehaviorSubject<Timestamped<Foo>> subject = BehaviorSubject.create();

    Observable<Foo> serviceCall() {
        return subject.filter(new Func1<Timestamped<Foo>, Boolean>() {
            @Override
            public Boolean call(Timestamped<Foo> tsFoo) {
                return tsFoo.getTimestampMillis() < expiry;
            }
        }).switchIfEmpty(serviceCall().timestamp().doOnNext(new Action1<Timestamped<Foo>>() {
            @Override
            public void call(Timestamped<Foo> tsFoo) {
                subject.onNext(tsFoo);
            }
        })
        .map(new Func1<Timestamped<Object>, Foo>() {
            @Override
            public Foo call(Timestamped<Object> tsFoo) {
                return tsFoo.getValue();
            }
        });
    }

关于java - RxJava : Read from cache until timestamp is expired,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47899554/

相关文章:

java - 不使用数组在另一个数字中查找一个数字

java - 无法使用 DBX 选择器错误创建链接 android

android - Eclipse 按钮​​,如 Step in、Step out、resume 等。不起作用

java - 创建具有内部数据库的 Java 小程序或 Windows 应用程序

java - java.lang.RuntimeException:无法启动 Activity ComponentInfo:java.lang.ClassCastException:无法转换为android.widget.Button

java - 将当前 Activity 传递给服务,以便该服务可以操作 View

java - 简化交错的 flatMap Observables 链

Android 相当于 javascript 的 setTimeout 和 clearTimeout?

java - RxJava 收集() & takeUntil()

java - RxJava : How to conditionally apply Operators to an Observable without breaking the chain