java - 从 Rxjava2 中的 Single.onErrorResumeNext 启动可观察链
问题描述
loadSingle
返回单个对象,如果失败我想调用getObservable(rsList)
哪个返回 Observable。我正在尝试,onErrorResumeNext
但它需要单个对象。我怎样才能调用getObservable(rsList)
失败loadSingle()
?
提前致谢!!
repo.loadSingle()
.subscribeOn(Schedulers.io())
.onErrorResumeNext {
repo.getObservable(rsList)
}
.flatMapObservable {
if (it != null && it.status == Status.SUCCESS) {
upRsList(it.data)
}
repo.getObservable(rsList)
}
({ //observable success
}, {
//observable error
})
API接口
interface HomeApi{
fun getSingel():Single<List<String>>
fun getObservable():Observable<HomeResponse>
}
解决方案
依赖项
testImplementation("org.junit.jupiter:junit-jupiter-api:5.6.2")
testRuntimeOnly("org.junit.platform:junit-platform-launcher:1.6.2")
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.6.2")
testRuntimeOnly("org.junit.vintage:junit-vintage-engine:5.6.2")
implementation "io.reactivex.rxjava3:rxjava:3.0.4"
implementation "io.reactivex.rxjava3:rxkotlin:3.0.0"
必修课
internal interface Repo {
fun loadSingle(): Single<Result<List<String>>>
fun getObservable(list: List<String>): Observable<String>
}
internal class RepoImpl : Repo {
override fun loadSingle(): Single<Result<List<String>>> {
return Single.error(RuntimeException("fail"))
}
override fun getObservable(list: List<String>): Observable<String> {
if (list === emptyList<String>()) {
return Observable.just("42")
}
return Observable.just("success")
}
}
internal sealed class Result<T> {
data class Success<T>(val value: T) : Result<T>()
data class Failure<T>(private val failure: Throwable) : Result<T>()
}
测试
通过#onErrorReturn 将错误包装为默认值,并相应地处理结果。
class So64751341 {
@Test
fun `64751341`() {
val repo: Repo = RepoImpl()
val testScheduler = TestScheduler()
val flatMapObservable = repo.loadSingle()
.subscribeOn(testScheduler)
.onErrorReturn { failure -> Result.Failure(failure) }
.flatMapObservable { result ->
when (result) {
is Result.Success -> repo.getObservable(result.value)
is Result.Failure -> repo.getObservable(emptyList())
}
}
val test = flatMapObservable.test()
testScheduler.triggerActions()
test // return default value 42 onError
.assertValue("42")
}
}
Repo#loadSingle() 同步抛出异常
internal class RepoExceptionImpl : Repo {
override fun loadSingle(): Single<Result<List<String>>> {
throw java.lang.RuntimeException("whatever")
}
override fun getObservable(list: List<String>): Observable<String> {
if (list === emptyList<String>()) {
return Observable.just("42")
}
return Observable.just("success")
}
}
测试
Repo#loadSingle 必须用 Single#defer 包装。Single#defer 将捕获异常并将其作为 #onError 发送给订阅者,然后由 #onErrorReturn 处理
@Test
fun `64751341_exception`() {
val repo: Repo = RepoExceptionImpl()
val testScheduler = TestScheduler()
val flatMapObservable = Single.defer {
repo.loadSingle()
}
.subscribeOn(testScheduler)
.onErrorReturn { failure -> Result.Failure(failure) }
.flatMapObservable { result ->
when (result) {
is Result.Success -> repo.getObservable(result.value)
is Result.Failure -> repo.getObservable(emptyList())
}
}
val test = flatMapObservable.test()
testScheduler.triggerActions()
test // return default value 42 onError
.assertValue("42")
}
推荐阅读
- html - css使用颜色从继承颜色,到另一个属性
- matlab - 如何在文本和数字之间只写数字(并将它们转换为列向量),如下所示
- vue.js - 为什么 Vue 不缓存方法结果?
- python - 使用 networkx 或 networkit 从边列表中为多个有向图创建路径表示
- jax-rs - Kumuluzee 微配置文件休息客户端 - 无法在错误响应中获取响应正文
- html - 我该如何搬家
在 ? - django - Django:获取点击按钮的ID
- c++ - c++ STL使用向量
调整大小失败 - python - 3-D 特征的 TFRecord 解析
- laravel - Laravel - 如何向 Laravel Spatie 权限添加额外的列