我有一个示例API请求,返回用户观看列表的列表。当用户加载观看列表屏幕时,我想要实现以下流程:
上述流程的问题在于,它对于每个数据源向下游(presenter)调用
我的问题是?
1. 实现上述逻辑的最佳方式是什么? 2. 我是否在DataManager(参见:
- 立即从DB缓存中加载数据(
cacheWatchList
) - 在后台启动RetroFit网络调用。
i.
onSuccess
返回apiWatchList
ii.onError
返回cacheWatchList
- 将
cacheWatchList
与apiWatchList
进行比较i. 相同 -> 一切正常,因为数据已经显示给用户,无需操作。
ii. 不同 -> 将
apiWatchList
保存到本地存储并将其发送到下游。
data class Watchlist(
val items: List<Repository> = emptyList()
)
LocalStore.kt (Android room)
fun saveUserWatchlist(repositories: List<Repository>): Completable {
return Completable.fromCallable {
watchlistDao.saveAllUserWatchlist(*repositories.toTypedArray())
}
}
RemoteStore.kt (Retrofit api调用)
fun getWatchlist(userId: UUID): Single<Watchlist?> {
return api.getWatchlist(userId)
}
DataManager.kt
fun getWatchlist(userId: UUID): Flowable<List<Repository>?> {
val localSource: Single<List<Repository>?> =
localStore.getUserWatchlist()
.subscribeOn(scheduler.computation)
val remoteSource: Single<List<Repository>> = remoteStore.getWatchlist(userId)
.map(Watchlist::items)
.doOnSuccess { items: List<Repository> ->
localStore.saveUserWatchlist(items)
.subscribeOn(scheduler.io)
.subscribe()
}
.onErrorResumeNext { throwable ->
if (throwable is IOException) {
return@onErrorResumeNext localStore.getUserWatchlist()
}
return@onErrorResumeNext Single.error(throwable)
}
.subscribeOn(scheduler.io)
return Single.concat(localSource, remoteSource)
}
上述流程的问题在于,它对于每个数据源向下游(presenter)调用
onNext
方法两次,即使这两个数据是相同的。我可以在presenter中进行数据差异逻辑并相应更新,但我希望DataManager
类为我处理逻辑(Clean Architecture、SOC)。我的问题是?
1. 实现上述逻辑的最佳方式是什么? 2. 我是否在DataManager(参见:
doOnSuccess
代码)中泄漏了内部订阅?当presenter被销毁时,我会处理外部订阅。
DataSource
无效吗? - pskinkLivePagedListProvider
,而所有逻辑都将在你的自定义DataSource
中实现。 - pskink