链接多个调用RxJava,Room和Retrofit

Est*_*ban 5 android rx-kotlin retrofit2 rx-java2 android-room

我正在使用RxJava/Kotlin和Room and Retrofit.我确信我刚开始学习RxJava时没有写东西.方案是我打电话检查数据库中是否有喜欢的记录并将它们放入List中,从API获取数据并将其插入数据库,使用上一个收藏夹列表更新数据库并获取所有记录,现在更新,列表.我得到了我的片段中的结果,但每次我得到它就好像我得到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)
}
Run Code Online (Sandbox Code Playgroud)

在我的 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())
}
Run Code Online (Sandbox Code Playgroud)

我实际上会在我的片段中获得列表,但正如我所说,它将永远不会受到喜爱,直到没有.

Moh*_*him 1

首先,尽量不要依赖副作用,这会使事情变得不可预测..例如这个函数

fun insertKafaniInDb(kafani: List<Kafana>) {
    Observable.fromCallable { kafanaDao.insertAll(kafani) }
            .subscribeOn(Schedulers.io())
            .subscribe {
                Timber.d("Inserted ${kafani.size} kafani from API in DB...")
            }
}
Run Code Online (Sandbox Code Playgroud)

它的返回类型是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...") }
  }
Run Code Online (Sandbox Code Playgroud)

其他返回 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())
  }
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助你。最后的话.. Rx 是关于排序你的想法并以功能方式插入你的逻辑.. 尽量避免使用onNext()它来更新全局变量,仅将其用于日志记录和非业务逻辑。