响应式编程之错误处理

267 阅读2分钟
public class HystrixObserver {

    public static void main(String[] args) {
        HystrixObserver hystrixObserver = new HystrixObserver();
        hystrixObserver.hystrix("ceshi");
    }

    public void hystrix(String username){

        /**
         * R call();
         */
        Func0<Observable<Object>> defer = new Func0<Observable<Object>>(){
            @Override
            public Observable<Object> call() {
                System.out.println("4.username = " + username);
                return Observable.just(2);
            }
        };
        /**
         * R call(T t);
         */
        Func1<Object,Object> map = new Func1<Object,Object>(){

            @Override
            public Object call(Object observable) {
                System.out.println("5.map username = " + username);
                int a = 1/0;
                if(observable instanceof Integer){
                    return ((Integer) observable)* 3;
                }
                return null;
            }
        };

        Observable.defer(new Func0<Observable<Object>>() {
            @Override
            public Observable<Object> call() {
                System.out.println("1.username = " + username);
                return Observable.defer(new Func0<Observable<Object>>() {
                    @Override
                    public Observable<Object> call() {
                        return Observable.just((Object) 12)
                                .map(map)
                                .doOnEach(new Action1<Notification<? super Object>>() {
                                    @Override
                                    public void call(Notification<? super Object> notification) {
                                        System.out.println("this is doOnEach1");
                                    }
                                }).onErrorResumeNext(new Func1<Throwable, Observable<?>>() {
                                    @Override
                                    public Observable<?> call(Throwable throwable) {
                                        System.out.println("this is onErrorResumeNext");
                                        return Observable.error(throwable);
                                    }
                                }).doOnError(new Action1<Throwable>() {
                                    @Override
                                    public void call(Throwable throwable) {
                                        System.out.println("this is doOnError");
                                    }
                                })
                                .onErrorReturn(new Func1<Throwable, Object>() {
                                    @Override
                                    public Object call(Throwable throwable) {
                                        System.out.println("this is onErrorReturn");
                                        return "this is onErrorReturn";
                                    }
                                });
                    }
                }).doOnNext(new Action1<Object>() {
                    @Override
                    public void call(Object o) {
                        System.out.println("this is doOnNext");
                    }
                });
            }
        }).subscribe(new Subscriber<Object>() {
            @Override
            public void onCompleted() {

            }

            @Override
            public void onError(Throwable e) {
                System.out.println("this is subscribe onError");
            }

            @Override
            public void onNext(Object o) {
                System.out.println("this is onNext o = " + o);
            }
        });
    }
}

1、onErrorResumeNext

public final Observable<T> onErrorResumeNext(final Func1<? super Throwable, ? extends Observable<? extends T>> resumeFunction) {
    return lift(new OperatorOnErrorResumeNextViaFunction<T>(resumeFunction));
}

By default, when an Observable encounters an error that prevents it from emitting the expected item to its Observer, the Observable invokes its Observer's onError method, and then quits without invoking any more of its Observer's methods. The onErrorResumeNext method changes this behavior. If you pass a function that returns an Observable (resumeFunction) to onErrorResumeNext, if the original Observable encounters an error, instead of invoking its Observer's onError method, it will instead relinquish control to the Observable returned from resumeFunction, which will invoke the Observer's onNext method if it is able to do so. In such a case, because no Observable necessarily invokes onError, the Observer may never know that an error happened。 默认一个被观察者遇到错误就会调用其onError方法,然后直接退出。如果onErrorResumeNext方法返回的是一个Observable,则控制权交由该Observable,由该Observable决定是继续传递错误【Observable.error】 还是转而调用其onNext方法。 场景:错误或者异常不会阻断主流程的继续执行。

2、doOnError

这种类型的Observable不会改变任何行为,

public final Observable<T> doOnError(final Action1<? super Throwable> onError) {
    Action1<T> onNext = Actions.empty();
    Action0 onCompleted = Actions.empty();
    Observer<T> observer = new ActionObserver<T>(onNext, onError, onCompleted);
    return unsafeCreate(new OnSubscribeDoOnEach<T>(this, observer));
}

3、onErrorReturn

不会向下游继续传递错误,相反是onNext方法。

public final Observable<T> onErrorReturn(Func1<? super Throwable, ? extends T> resumeFunction) {
    return lift((Operator<T, T>)OperatorOnErrorResumeNextViaFunction.withSingle(resumeFunction));
}

注释:Instructs an Observable to emit an item (returned by a specified function) rather than invoking {@link Observer#onError onError} if it encounters an error。

该类型的被观察者遇到错误不会传递错误,相反利用新的Observable发射新的元素。 即下游Observable不是执行OnError,而是OnNext。

By default, when an Observable encounters an error that prevents it from emitting the expected item to its Observer, the Observable invokes its Observer's onError method, and then quits without invoking any more of its Observer's methods. The onErrorReturn method changes this behavior. If you pass a function (resumeFunction) to an Observable's onErrorReturn method, if the original Observable encounters an error, instead of invoking its Observer's onError method, it will instead emit the return value of resumeFunction。