【问题标题】:RxAndroid - Handle Errors with Zip operatorRxAndroid - 使用 Zip 运算符处理错误
【发布时间】:2017-10-09 13:56:10
【问题描述】:

我正在尝试找到一种方法来并行执行请求并在每个 observable 完成时处理它们。尽管当所有可观察对象都给出响应时一切正常,但我没有看到在一切完成后处理所有错误的方法。

这是一个 zip 运算符的示例,它基本上是并行执行 2 个请求:

Observable.zip(
                getObservable1()
                        .onErrorResumeNext { errorThrowable: Throwable ->
                            Observable.error(ErrorEntity(Type.ONE, errorThrowable))
                        }.subscribeOn(Schedulers.io()),
                getObservable2()
                        .onErrorResumeNext { errorThrowable: Throwable ->
                            Observable.error(ErrorEntity(Type.TWO, errorThrowable))
                        }.subscribeOn(Schedulers.io()),
                BiFunction { value1: String, value2: String ->
                    return@BiFunction value1 + value2
                })
                //execute requests should be on io() thread
                .subscribeOn(Schedulers.io())
                //there are other tasks inside subscriber that need io() thread
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(
                        { result ->
                            Snackbar.make(view, "Replace with your own action " + result, Snackbar.LENGTH_LONG)
                                    .setAction("Action", null).show()
                        },
                        { error ->
                            Log.d("TAG", "Error is : " + (error as ErrorEntity).error.message)
                        }
                )


private fun getObservable1(): Observable<String> {
    return Observable.defer {
        throw Throwable("Error 1")
    }
}

private fun getObservable2(): Observable<String> {
    return Observable.defer {
        throw Throwable("Error 2")
    }
}

这种方法的问题是没有像 BiFunction 那样为成功案例加入每个错误的机制。因此,zip 运算符只会触发第一个错误,而忽略其他错误。

输出:

D/TAG: Error is : Error 1

只有在 zip 中的每个可观察对象完成或出现错误后,有什么方法可以检索所有错误吗?

我的主要目标是查看哪些请求出错并仅在用户出现对话框询问他是否要重试失败的请求后执行那些请求。

【问题讨论】:

  • 如果您在下一次恢复时没有继续出错,而是使用包含错误的包装器对象,也许会更容易?
  • 这是一个可能的解决方案,谢谢。但是,它并没有破坏使用 onError() onNext() 方法的目的吗?
  • '使用 onError() onNext() 方法的目的是什么?这取决于您在系统中定义为 Error 的内容。我同意@LordRaydenMK 提到的文章以及this oneOnError 应该用于您的应用程序/系统不知道如何处理的情况。每次系统不遵循“快乐路径”时,您都不应该抛出异常。

标签: error-handling kotlin rx-java rx-android rx-java2


【解决方案1】:

您可以使用数据类为您的可观察对象建模。例如

sealed class Response {
    data class Success(val data: String) : Response()
    data class Error(val t: Throwable) : Response()
}

然后你可以像这样将你的 observables 映射到 Response:

val first: Observable<Response> = observable1
        .map<Response> { Response.Success(it) }
        .onErrorReturn { Response.Error(it) }

val second: Observable<Response> = observable2
        .map<Response> { Response.Success(it) }
        .onErrorReturn { Response.Error(it) }

您可以将它们组合起来:

Observable.zip(
        first,
        second,
        BiFunction { t1: Response, t2: Response -> Pair(t1, t2) }
).subscribe({println(it)})

这个打印:

(错误(t=java.lang.Exception:错误 1),错误(t=java.lang.Exception: 错误 2))

也可以看看this article

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-05-11
    • 2017-05-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-05
    • 2023-03-15
    相关资源
    最近更新 更多