ConcatMap没有跳过错误的选项 - RxJava

时间:2018-01-05 10:09:41

标签: java android rx-java rx-android

考虑这个例子: 我按顺序下载文件。如果一次下载失败,则应该转到下一次。 Psudo代码:

Observable.from(urls)
 .concatMap(url -> downloadObservable(url)) 

如果下载失败,则无法移至下一个网址。

我无法跳过onErrorResumeNext(),因为我只想转到下一个网址。有人可以帮忙吗?

4 个答案:

答案 0 :(得分:1)

有一个运算符:concatMapDelayError,因为1.3。一般情况下,如果有一个原因可能会延迟错误,直到所有来源都被完全消耗,那么可能会有opNameDelayError运算符。

Observable.from(urls)
    .concatMapDelayError(url -> downloadObservable(url))
    .doOnError(error -> {
        if (error instanceof CompositeException) {
           System.out.println(((CompositeException)error).getExceptions().size());
        } else {
            System.out.println(1);
        }
    });

doOnError附录来自RxJava问题列表中更新的OP cross post。)

答案 1 :(得分:0)

根据:https://github.com/ReactiveX/RxJava/issues/3870,没有办法做到这一点。当然,您可以引入一些其他错误处理,即在downloadObservable中处理错误,然后过滤空答案。

答案 2 :(得分:0)

如果您使用的是RxJava 1,那么快速而肮脏的解决方案是在下载失败时返回null,然后将其过滤掉:

Observable
    .from(urls)
    .concatMap(url -> downloadObservable(url).onErrorReturn(null))
    .filter(result -> result != null)

一个更好的解决方案是为结果创建一个包装器,使用wasSuccessful()之类的方法来检查过滤器,并使用类似getResult()的方法从包装器中提取结果。这样你就不必处理空值。

答案 3 :(得分:0)

你必须认为这是一个管道,所以,如果你不想停止管道的排放,你必须控制错误并返回一些东西,以便继续下一次发射。

使用onErrorResumeNext并且之后不停止发射的唯一方法是,它是否在flatMap中执行

Observable.from(urls)
 .flatMap(url -> downloadObservable(url)
                   .onErrorResumeNext(t -> Observable.just("Something went wrong")))) 

您可以在此处查看示例https://github.com/politrons/reactive/blob/master/src/test/java/rx/observables/errors/ObservableExceptions.java