【发布时间】:2017-10-17 18:42:00
【问题描述】:
我正在使用 SqlBrite/SqlDelight 在 RxJava 中实现存储库模式,用于离线数据存储和 Http 请求的改造
这是一个示例:
protected Observable<List<Item>> getItemsFromDb() {
return database.createQuery(tableName(), selectAllStatement())
.mapToList(cursor -> selectAllMapper().map(cursor));
}
public Observable<List<Item>>getItems(){
Observable<List<Item>> server = getRequest()
.doOnNext(items -> {
BriteDatabase.Transaction transaction = database.newTransaction();
for (Item item : items){
database.insert(tableName(), contentValues(item));
}
transaction.markSuccessful();
transaction.end();
})
.flatMap(items -> getItemsFromDbById())
.delaySubscription(200, TimeUnit.MILLISECONDS);
Observable<List<Item>> db = getItemsFromDbById(id)
.filter(items -> items != null && items.size() > 0);
return Observable.amb(db, server).doOnSubscribe(() -> server.subscribe(items -> {}, throwable -> {}));
}
当前实现使用Observable.amb 获取最新的2 个流,并在db 有数据或服务器的情况下返回db 流。为了防止在没有互联网的情况下提前失败,server 上面有一个delaySubscription 和200ms。
我尝试使用 Observable.concat,但 SqlBrite 流从不调用 onComplete,因此永远不会触发 server observable。
我也尝试了Observable.combineLatest,但没有成功,因为它一直在等待server observable 在发出任何东西之前返回数据,而Observable.switchOnNext 也没有工作。
我正在寻找的是一个存储库:
- 保持对 SqlBrite (DB) 的订阅处于打开状态,以防数据库更新
- 始终从服务器获取数据并将其写入数据库
- 如果数据库中没有任何内容并且网络请求仍在进行中,则不应发出空结果。这是因为在第一次加载的情况下,用户应该会看到一个进度条。
【问题讨论】:
-
我不明白你想要什么。
-
@DeanXu 我已经更新了问题。
-
让我更正一下,您想一次执行 2 个操作,并希望在成功的情况下合并结果,如果失败,您想用观察者管理该流程!?
标签: android retrofit rx-java sqlbrite sqldelight