我假設你有可觀察到的可以得到dat一個來自本地和遠程象下面這樣:
final Observable<Page> localResult = mSearchLocalDataSource.search(query);
final Observable<Page> remoteResult = mSearchRemoteDataSource.search(query)
.doOnNext(new Action1<Page>() {
@Override
public void call(Page page) {
if (page != null) {
mSearchLocalDataSource.save(query, page);
mResultCache.put(query, page);
}
}
});
然後你可以將它們映射並獲得第一,如果沒有遠程使用,這意味着,如果當地可用的使用本地:
return Observable.concat(localResult, remoteResult)
.first()
.map(new Func1<Page, Page>() {
@Override
public Page call(Page page) {
if (page == null) {
throw new NoSuchElementException("No result found!");
}
return page;
}
});
,並訂閱它象下面這樣:
mCompositeSubscription.clear();
final Subscription subscription = mSearchRepository.search(this.mQuery)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<Page>() {
@Override
public void onCompleted() {
// Completed
}
@Override
public void onError(Throwable e) {
mView.onDefaultMessage(e.getMessage());
}
@Override
public void onNext(Page page) {
mView.onDefaultMessage(page.getContent());
}
});
mCompositeSubscription.add(subscription);
更多細節或例子,你可以檢查我的github回購: https://github.com/savepopulation/wikilight
祝你好運!
編輯:
你可以試試當地的觀察到如下圖所示。只需檢查是否有記錄並返回空的可觀察值。
@Override
public Observable<Page> search(@NonNull final String query) {
return Observable.create(new Observable.OnSubscribe<Page>() {
@Override
public void call(Subscriber<? super Page> subscriber) {
final Realm realm = Realm.getInstance(mRealmConfiguration);
final Page page = realm.where(Page.class)
.equalTo("query", query)
.findFirst();
if (page != null && page.isLoaded() && page.isValid()) {
Log.i("data from", "realm");
subscriber.onNext(realm.copyFromRealm(page));
} else {
Observable.empty();
}
subscriber.onCompleted();
realm.close();
}
});
}
編輯2:
當您從本地CONCAT返回null,第一是行不通的,你的遙控器將不會被調用,因爲空是指觀察到的回報空,但仍然可以觀察到。當你用concat返回observable.empty時,首先這意味着observable不能從本地發出任何東西,因此它可以從遠程發出。
謝謝。如果我想爲每個請求創建新的數據,這個解決方案工作的很好,但在我的情況下,緩存的項目有一個到期日期,所以我只想打網絡,如果項目從未緩存,或者如果他們過期。我的數據庫查詢將返回該場景中的空列表(未緩存或過期),所以我想有一種方法來運行第二個observable,只有當第一個返回空列表時。我雖然帶有條件函數的first()運算符會這樣做,但即使在緩存爲空的情況下,網絡observable也永遠不會運行在我的原始代碼中。有任何想法嗎? – Francesc
嗯,是的,我編輯了我的文章。看看是否適合你。 – ehehhh
謝謝,這個工程是一個簡潔的解決方案。我仍然不明白爲什麼我原來的解決方案不起作用,因此我需要研究它,但這種解決方案很適合我的需求。再次感謝。 – Francesc