RxJava Single.toCompletable()似乎以某种方式破坏了Single

Mic*_*ovo 3 android rx-java2

注意:事实证明toCompletable()并不是错误,而是调用代码。调用代码使得更改此方法使其起作用(或不起作用)。


我有以下方法。它返回一个Single。有用。执行内部代码,以便remoteDataSource Single下载数据和其中的代码doOnSuccess运行中,我可以在其中断点。

但是,如果像第二个示例中那样将其转换为可完成对象,它将停止工作。不会下载数据,并且其中的代码doOnSuccess永远不会运行。

我想在此方法中将其转换为Completable,因为调用此方法的方法不需要数据,仅需要成功/错误结果。

知道为什么会这样吗?

它在文档中说

返回一个{@link Completable},它会丢弃{@link Single}的结果,并在此源{@link Single}调用{@code onSuccess}时调用{@code onComplete}。错误终端事件被传播。

但是我认为这意味着它将丢弃调用方法的内容,而不是当前方法的内容。通过转换为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()
      }
}
Run Code Online (Sandbox Code Playgroud)

破碎:

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

更新:

好的,这是我的调用方法。是的,这有点复杂。也许那里的东西导致了问题。

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 {
            ...
        }
}
Run Code Online (Sandbox Code Playgroud)

更新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 {
            ...
        }
}
Run Code Online (Sandbox Code Playgroud)

San*_*0rd 5

我编写了一些代码来进行尝试,并且可以正常工作:

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

completable.subscribe()
Run Code Online (Sandbox Code Playgroud)

确保您正在呼叫具有单一和完整版本的订阅。