美文网首页每天一个秃头小技巧java收藏
【RxJava】操作符:onErrorResumeNext

【RxJava】操作符:onErrorResumeNext

作者: littlefogcat | 来源:发表于2022-02-09 00:44 被阅读0次

    阻止 onError

    onErrorResumeNext 的目的是使 ObservableSource 将控制权传递给另一个 ObservableSource,而不是在遇到错误时调用 onError。(Instructs an ObservableSource to pass control to another ObservableSource rather than invoking onError if it encounters an error.

    默认情况下,如果数据源遇到了错误,那么就会调用观察者的 onError 回调。当使用 onErrorResumeNext 之后,则不会调用 onError,而是采用传入的数据源进行接下来的操作。

    例如:

    Observable.<Integer>create(emitter -> {
                emitter.onNext(1);
                emitter.onNext(2);
                emitter.onError(new RuntimeException());
                emitter.onNext(3);
                emitter.onComplete();
            })
            .subscribe(i -> System.out.println("onNext: " + i),
                    e -> System.out.println("onError: " + e),
                    () -> System.out.println("complete"));
    

    对于以上代码,会依次打印:

    onNext: 1
    onNext: 2
    onError: java.lang.RuntimeException

    这时候,如果使用 onErrorResumeNext,则会阻止进入 onError,并按照传入的数据源进行发射:

    Observable.<Integer>create(emitter -> {
                emitter.onNext(1);
                emitter.onNext(2);
                emitter.onError(new RuntimeException());
                emitter.onNext(3);
                emitter.onComplete();
            })
            .onErrorResumeNext(observer -> {
                observer.onNext(4);
                observer.onComplete();
            })
            .subscribe(i -> System.out.println("onNext: " + i),
                    e -> System.out.println("onError: " + e),
                    () -> System.out.println("complete"));
    

    以上代码会依次打印:

    onNext: 1
    onNext: 2
    onNext: 4
    complete

    防止序列中断

    需要注意的是,onErrorResumeNext 并不会使原始的数据源继续发射,而只是换了一个数据源,相当于启用了备胎。如上述代码中,最后并不会收到数字 3,而是收到了 4

    基于这点,对于任务序列,则需要对序列中的每个任务都调用了 onErrorResumeNext,以保证序列不被中断。

    例如,现在有一个下载器 Downloader,包含了一个 download 方法,其返回一个 Observable<DownloadResult> 对象:

    class Downloader {
        public static Observable<DownloadResult> download(String url) {
            // ...
        }
    }
    

    现在,要进行批量下载:

    List<String> urls = Arrays.asList("foo", "bar", "hello");
    Observable.fromIterable(urls)
            .flatMap(url -> Downloader.download(url))
            .subscribe(result -> System.out.println("onNext: " + result),
                    e -> System.out.println("onError: " + e),
                    () -> System.out.println("onComplete"));
    

    在以上代码中,由于 download 方法可能出错,从而中断序列,导致观察者无法收到后续的任何通知。使用 onErrorResumeNext 可以在出错之后避免整个序列被中断。

    List<String> urls = Arrays.asList("foo", "bar", "hello");
    Observable.fromIterable(urls)
            .flatMap(url -> Downloader.download(url)
                    .onErrorResumeNext(observer -> {
                        observer.onNext(Result.FAILURE);
                        observer.onComplete();
                    }))
            .subscribe(result -> System.out.println("onNext: " + result),
                    e -> System.out.println("onError: " + e),
                    () -> System.out.println("onComplete"));
    

    要注意的是,一旦设置了 onErrorResumeNext,观察者将无法知道中途出现了异常,不过这一点可以通过特定的错误码来识别。

    相关文章

      网友评论

        本文标题:【RxJava】操作符:onErrorResumeNext

        本文链接:https://www.haomeiwen.com/subject/rpvikrtx.html