RxJava Single.toCompletable (), кажется, как-то ломает Single - PullRequest
0 голосов
/ 07 июня 2018

Примечание : Оказывается, toCompletable() не был ошибкой, но вместо этого это был код вызова.Код вызова был таким, что изменение этого метода заставляло его работать (или не работать).


У меня есть следующий метод.Возвращает сингл.Оно работает.Код внутри выполнен так, что remoteDataSource Single загружает данные, и код в doOnSuccess запускается, и я могу там установить точку останова.

Однако, если я преобразую его в завершаемый, как во втором примере, он останавливаетсяза работой.Данные не загружаются, и код внутри doOnSuccess никогда не выполняется.

Я хочу преобразовать его в Completable в этом методе, потому что метод, который вызывает этот метод, не нуждается в данных, только в успехе /результат ошибки.

Есть идеи, почему это происходит?

В документации сказано:

Возвращает {@link Completable}, который отбрасывает результат {@link Single} и вызывает {@code onComplete}, когда этот источник {@link Single} вызывает {@code onSuccess}.Событие ошибки терминала распространяется.

Но я подумал, что это означает, что он будет отбрасывать вещи для вызывающего метода, а не для текущего метода.При преобразовании в Completable даже данные RemoteDataSource Single не будут загружать данные.

Работает:

override fun downloadSomethingList(): Single<List<Something>> {
    return remoteDataSource.getSomethingList(getHash(SOMETHING_HASH))
      .doOnSuccess { it: Map<String, List<Something>>
        saveHash(SOMETHING_HASH, it.keys.first())
        localDataSource.replaceSomethingList(it.values.first())
      }.map {
          it.values.first()
      }
}

Broken:

override fun downloadSomethingList(): Completable {
    return remoteDataSource.getSomethingList(getHash(SOMETHING_HASH))
        .doOnSuccess { it: Map<String, List<Something>>
          saveHash(SOMETHING_HASH, it.keys.first())
          localDataSource.replaceSomethingList(it.values.first())
        }.toCompletable()
}

Обновление:

Хорошо, вот мой вызывающий метод.Да, это немного сложно.Возможно, что-то там вызывает проблему.

fun downloadData(): Completable {
    ...
    return repository.downloadThing1()
        .flatMap { downloadedThing1 ->
            ...
            repository.downloadThing2().toSingle()
        }
        .flatMap {
            repository.getThing2()
        }.flatMap { thing2 ->
            ...
            repository.saveThing1(thing1).toSingle()
        }
        .flatMap {
            if ("some condition") {
                repository.downloadThing3()
                    .andThen(repository.downloadThing4())
                    .andThen(repository.downloadThing5())
                    .andThen(repository.downloadThing6()).toSingle()
            } else {
                Completable.complete().toSingle()
            }
        }.toCompletable()
        .doOnComplete {
            ...
        }
}

Обновление 2:

Если я использую следующий код вызова, это работает! Итак, извлеченный урок состоит в том, что вызывающий код может определенно сломать восходящий поток .Точнее, я думаю, что это были все toSingle() звонки.Вместо этого я обнаружил flatMapCompletable, который, кажется, предназначен для этой цели.

Так как в исходном коде вопроса не было ничего плохого, мне пришлось присуждать очки Sanf0rd за то, что он показал, что этокейс.

fun downloadData(): Completable {
    ...
    return repository.downloadThing1()
        .flatMapCompletable { downloadedThing1 ->
            ...
            repository.downloadThing2()
        }.andThen(repository.getThing2())
        .flatMapCompletable { thing2 ->
            ...
            repository.saveThing1(thing1)
            if ("some condition") {
                repository.downloadThing3()
                    .andThen(repository.downloadThing4())
                    .andThen(repository.downloadThing5())
                    .andThen(repository.downloadThing6())
            } else {
                Completable.complete()
            }
        }
        .doOnComplete {
            ...
        }
}

1 Ответ

0 голосов
/ 07 июня 2018

Я сделал небольшой кусочек кода, чтобы попробовать его, и он работает:

val single = Single.create<Int> { emitter ->  emitter.onSuccess(5) }
val completable = single.map { it * 2 }.doOnSuccess { Log.d("MyTag", "$it")}.toCompletable()

completable.subscribe()

Убедитесь, что вы звоните, подпишитесь на версию Single и Completable.

...