【问题标题】:FlatMapCompletable doesn't continue Rx chain but flatmap with a completable with "andThen(Observable.just(true)" does work?FlatMapCompletable 不会继续 Rx 链,但是带有 "andThen(Observable.just(true)" 的可完成的平面图可以工作吗?
【发布时间】:2019-03-18 17:22:53
【问题描述】:

我正在尝试将一个可完成链接到我的 Rx 链中,当我这样做时,链永远不会在 onError 或 onComplete 中完成。

当我单步执行代码时,我的可完成代码被执行。我什至可以添加日志记录并看到它登录到它自己的 doOnComplete()

下面会记录“我已完成”,但不会进入错误或完成回调。

 profileRepo.getLocalProfileIfAvailableElseRemote()
                .flatMapCompletable { profile ->
                    userRoutingRepo.disableRule(profile.account_uid, userRoutingRule.id)
                            .doOnComplete {
                                Log.i("I COMPLETED", "I COMPLETED")
                            }
                }
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribeBy(
                        onError = { error ->
                            //do error
                        },
                        onComplete = {
                           //do success
                        }
                ).addTo(disposable)

如果我改为使用 flatMap 并使用 andThen 返回一个布尔可观察对象,它将起作用

 profileRepo.getLocalProfileIfAvailableElseRemote()
                .flatMap { profile ->
                    userRoutingRepo.disableRule(profile.account_uid, userRoutingRule.id)
                            .doOnComplete {
                                Log.i("I COMPLETED", "I COMPLETED")
                            }.andThen(Observable.just(true))
                }
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribeBy(
                        onError = { error ->
                         //do error
                        },
                        onNext = {
                           //do next
                        }
                ).addTo(disposable)

我尝试在 flatMapCompletable 版本中添加“andThen”并调用 Completable.complete() 但这也不起作用?

我不知道为什么我的 Completable 正在完成,但拒绝使用 flatMapCompletable?

编辑:这是我的完整尝试的更新,但不起作用

注意userRoutingService.disableRule(accountUid, ruleId)是改造接口

 profileRepo.getLocalProfileIfAvailableElseRemote()
                .flatMapCompletable { profile ->
                    userRoutingRepo.disableRule(profile.account_uid, userRoutingRule.id)
                            .andThen(Completable.complete())
                }
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribeBy(
                        onError = { error ->
                          Log.i("TAG", "ERROR")
                        },
                        onComplete = {
                            Log.i("TAG", "COMPLETE")
                        }
                ).addTo(disposable)

 override fun disableRule(accountUid: String, ruleId: String): Completable {
        return activeStateToggler(userRoutingSourceApi.disableRule(accountUid, ruleId),
                ruleId,
                false)
    }



override fun disableRule(accountUid: String, ruleId: String): Completable {
        return userRoutingService.disableRule(accountUid, ruleId)
                .doOnError { error ->
                    authenticationValidator.handleAuthenticationExceptions(error)
                }
    }

    private fun activeStateToggler(completable: Completable,
                                   ruleId: String,
                                   stateOnSuccess: Boolean
    ): Completable {
        return completable
                .doOnSubscribe {
                    stateTogglingInProgress.add(ruleId)
                }
                .doOnComplete {
                    stateTogglingInProgress.remove(ruleId)
                    getLocalUserRule(ruleId)?.active = stateOnSuccess
                    stateTogglingInProgressPublishSubject.onNext(UserRoutingStateToggleSubjectType.Success)
                }
                .doOnError {
                    stateTogglingInProgress.remove(ruleId)
                    stateTogglingInProgressPublishSubject.onNext(UserRoutingStateToggleSubjectType.Error(
                            it))
                }
    }

【问题讨论】:

    标签: android rx-java2


    【解决方案1】:

    这就是 flatMapCompletable 所做的:

    将上游 Observable 的每个元素映射到 CompletableSources 中, 订阅它们并等到上游和所有 CompletableSources 完成。

    使用 flatMapCompletable 时,返回的 Completable 会等待上游的 Observable 终端事件(onComplete)。

    使用 flatMapCompletable 时,仅当您确定链中的所有内容都已完成时才使用它。

    在您的情况下,它不起作用,因为您的源 Observable 很热并且永远不会完成。

    【讨论】:

      【解决方案2】:

      使用flatMapCompletable时,需要自己返回Completable.complete()

      编辑:

       profileRepo.getLocalProfileIfAvailableElseRemote()
           .flatMap { profile ->
               userRoutingRepo.disableRule(profile.account_uid, userRoutingRule.id)
                   .doOnComplete { Log.i("I COMPLETED", "I COMPLETED") } }
           .flatMapCompletable { () -> { Completable.complete() } }
           .subscribeOn(Schedulers.io())
           .observeOn(AndroidSchedulers.mainThread())
           .subscribeBy(
               onError = { error ->
                   //do error
               },
               onNext = {
                   //do next
               }
          ).addTo(disposable)
      

      编辑2:因为disposableRuleCompletable

       profileRepo.getLocalProfileIfAvailableElseRemote()
           .flatMapCompletable { profile ->
               userRoutingRepo.disableRule(profile.account_uid, userRoutingRule.id)
                   .doOnComplete { Log.i("I COMPLETED", "I COMPLETED") }
                   .andThen(Completable.complete().doOnCompleted { Log.i("comp2", "comp2")) }
           .subscribeOn(Schedulers.io())
           .observeOn(AndroidSchedulers.mainThread())
           .subscribeBy(
               onError = { error ->
                   //do error
               },
               onNext = {
                   //do next
               }
          ).addTo(disposable)
      

      编辑 3:工作示例

      Observable.just(1)
          .flatMapCompletable { profile ->
              Completable.complete()
                  .doOnComplete { Log.i("I COMPLETED", "I COMPLETED") }
                  .andThen(Completable.complete().doOnComplete { Log.i("I COMPLETED", "I COMPLETED 2") })}
          .subscribeBy(
              onError = { error ->
              },
              onComplete = {
                  Log.d("I COMPLETED", "I COMPLETED 3")
              })
      

      【讨论】:

      • 那没用?这没有完成。 .flatMapCompletable { profile -> userRoutingRepo.disableRule(profile.account_uid, userRoutingRule.id).andThen(Completable.complete()) }
      • 编辑无法编译。它给出了一个错误,因为禁用规则是一个可完成的,但它期待一个可观察的。
      • Edit2 又回到了我最初遇到的同样问题。 disableRule 调用之后的任何内容及其 .doOnComplete 都不会执行,包括 andThen。 onError 或 onComplete 的订阅永远不会到达 =(
      • 发布您的整个代码。这对我有用。确保你使用.andThen() 而不是.andThen { }
      • 您发布的内容没有使用“真正的”可完成,但当禁用规则的返回结果是可完成时,它不起作用。我实际上不想在 andThe 中添加任何额外的逻辑,我只是​​想弄清楚如何让它读起来完整。我用完整的禁用规则逻辑更新了我的问题,所有这些都可以正确执行。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-08-30
      • 1970-01-01
      • 1970-01-01
      • 2010-12-18
      • 2012-01-08
      • 1970-01-01
      • 2010-12-24
      相关资源
      最近更新 更多