[英]RxJava building cache with observables for android
我很難理解如何使用 RxJava 構建緩存。 這個想法是我需要從內存緩存中獲取數據或從我的數據庫 (dynamoDb) 加載。 但是,這個緩存應該在片段和/或線程之間共享。 因此,我需要返回當前正在運行但尚未完成的現有 observable。 這允許線程趕上而不是做不必要的工作。 我是 RxJava 的新手,所以這就是我想到的草圖(為簡潔起見,缺少一些代碼):
public class DBCache<K, T> {
private final ConcurrentHashMap<K, Set<T>> resultCache = new ConcurrentHashMap<>;
private final ConcurrentHashMap<K, Observable<Set<T>>> observableCache = new ConcurrentHashMap<>;
private Observable<Set<T>> getFromCache(final DynamoDbCacheKey<K, T> query) {
return Observable.create(new Observable.OnSubscribe<Set<T>>() {
@Override
public void call(Subscriber<? super Set<T>> subscriber) {
Set<T> results = resultCache.get(query.getKey());
if (results != null && results.size() > 0) {
subscriber.onNext(results);
}
subscriber.onCompleted();
}
});
}
public Observable<Set<T>> get(final QueryCacheKey<K, T> query){
Observable<Set<T>> cachedObservable = observableCache.get(query.getKey());
if (cachedObservable != null) {
return cachedObservable;
}
Observable<Set<T>> observable = Observable
.concat(getFromCache(query), getFromNetwork(query))
.first()
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.cache();
observableCache.putIfAbsent(query.getKey(), observable);
return observable;
}
private Observable<Set<T>> getFromNetwork(final QueryCacheKey<K, T> query) {
return Observable.create(new Observable.OnSubscribe<Set<T>>() {
@Override
public void call(Subscriber<? super Set<T>> subscriber) {
try {
Set<T> results = loadFromDb(query); //omitted
resultCache.putIfAbsent(query.getKey(), results);
subscriber.onNext(results);
subscriber.onCompleted();
observableCache.remove(query.getKey());
} catch (Exception exception) {
subscriber.onError(exception);
}
}
});
}
}
有沒有更好的方法通過 RxJava 實現這一點(對緩存策略不感興趣)。 有什么想法嗎?
下面是一個簡單的緩存和檢索值的例子:
public class RxCache<K, V> {
final ConcurrentHashMap<K, AsyncSubject<V>> cache;
final Func1<K, Observable<V>> valueGenerator;
public RxCache(Func1<K, Observable<V>> valueGenerator) {
this.valueGenerator = valueGenerator;
this.cache = new ConcurrentHashMap<>();
}
public Observable<V> get(K key) {
AsyncSubject<V> o = cache.get(key);
if (o != null) {
return o;
}
o = AsyncSubject.create();
AsyncSubject<V> p = cache.putIfAbsent(key, o);
if (p != null) {
return p;
}
valueGenerator.call(key).subscribe(o);
return o;
}
public void remove(K key) {
cache.remove(key);
}
}
如果您有多個值,請將AsyncSubject
替換為ReplaySubject
。
您可以使用BehaviorSubject
應用緩存,創建一個Observable
,然后將其轉換為BehaviorSubject
,然后訂閱此Subject
以獲取您的數據。
現在這個Subject
將作為一個Observable
做出反應,當訂閱它時,它會給你獲取的最新數據,並在更新時發出新數據。
在此處查看更多詳細信息和實施: https : //medium.com/@jaerencoathup/repository-pattern-using-rxjava-and-room-4ce79e4ffc5c
另一種方法: https : //medium.com/@elye.project/rxjava-clean-way-of-prefetching-data-and-use-later-54800f2652d4
通過簡單示例了解更多關於 Subjects: https : //blog.mindorks.com/understanding-rxjava-subject-publish-replay-behavior-and-async-subject-224d663d452f
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.