我正在将RxJava/Kotlin与Room and Retrofit一起使用。我确定我刚开始学习RxJava时就不会写东西了。场景是我打电话检查数据库中是否有喜欢的记录,并将它们保存在列表中,从API获取数据并将其插入到数据库中,使用先前的收藏夹列表更新数据库,然后将所有记录作为一个现在更新,列表。我在 fragment 中得到结果,但是每次得到它时,就好像我少了1个喜欢的项目,直到没有喜欢的项目为止。Repository
fun getKafaniFromApi(): Observable<List<Kafana>> {
return apiService.getKafani().toObservable().doOnNext {
insertKafaniInDb(it)
}
}
fun getKafaniFromDb(): Observable<List<Kafana>> {
return kafanaDao.getKafani().toObservable()
}
fun insertKafaniInDb(kafani: List<Kafana>) {
Observable.fromCallable { kafanaDao.insertAll(kafani) }
.subscribeOn(Schedulers.io())
.subscribe {
Timber.d("Inserted ${kafani.size} kafani from API in DB...")
}
}
fun getFavoriteKafani(): Single<List<Kafana>> {
return kafanaDao.getFavoriteKafani()
}
fun setKafanaFavorite(kafana: Kafana, isFavorite: Int) {
return kafanaDao.setFavourite(kafana.name, isFavorite)
}
fun updateFavoriteKafana(kafana: Kafana) {
return kafanaDao.updateFavoriteKafana(kafana)
}
然后在我的
viewmodel
中fun get(): Observable<List<Kafana>> {
return kafanaRepository.getFavoriteKafani()
.toObservable()
.doOnNext { kafaniList = it }
.flatMap { kafanaRepository.getKafaniFromApi() }
.doOnNext { kafaniList?.forEach { kafanaRepository.updateFavoriteKafana(it) } }
.flatMap { kafanaRepository.getKafaniFromDb() }
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
}
我实际上会在我的 fragment 中找到该列表,但是,正如我所说,在没有任何人喜欢它之前,它将永远是一个不那么受欢迎的列表。
最佳答案
首先,请尝试不要依赖于副作用,这会使事情变得不可预测..例如,此功能
fun insertKafaniInDb(kafani: List<Kafana>) {
Observable.fromCallable { kafanaDao.insertAll(kafani) }
.subscribeOn(Schedulers.io())
.subscribe {
Timber.d("Inserted ${kafani.size} kafani from API in DB...")
}
}
它的返回类型是Unit,最好将其包含在流中,这是通过转换为
Completable
来完成的,因此它将是这样的 fun insertKafaniInDb(kafani: List<Kafana>) {
return Observable.fromAction { kafanaDao.insertAll(kafani) }
.subscribeOn(Schedulers.io())
.doOnComplete { Timber.d("Inserted ${kafani.size} kafani from API in DB...") }
}
其他返回Unit的函数(java中为void)应以相同的方式转换为completabel。因此,现在我将尝试在不使用副作用的情况下重写您的逻辑。并解释每个步骤。
fun getUpdatedData(): Single<MutableList<String>>? {
return kafanaRepository.getFavoriteKafani()
.toObservable()
.flatMap { Observable.fromIterable(it) } //to iterate on favorite items
.flatMap { localItem ->
kafanaRepository.getKafaniFromApi()
.flatMap { Observable.fromIterable(it) } //to iterate api items
.filter { localItem == it } //search for the favorite item in Api response
.flatMap {
//we update this item then we pass it after update
kafanaRepository.updateFavoriteKafana(it)
.andThen(Observable.just(it))
}
.defaultIfEmpty(localItem) //if it's not found, then no update needed we take this it.
}.toList() // we collect the updated and non updated local items to list
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
}
希望这可以对您有所帮助。
最后的话.. Rx是关于整理您的思想并以功能性方式插入您的逻辑。.尽量避免使用
onNext()
更新全局变量,仅将其用于记录和非业务逻辑。关于android - 链接多个调用RxJava,Room和Retrofit,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/48126761/