错误处理运算符
有助于从Observable中恢复错误通知的操作符。Rx错误处理有两个类别的运算符:
Catch类:Catch运算符拦截来自源Observable的onError通知,而不是将其传递给任何观察者,将其替换为其他项目或项目序列,可能允许生成的Observable正常终止或根本不终止;
Retry类:如果源Observable发出错误,请重新订阅它,希望它能完成而不会出错。重试操作符通过不将该调用传递给其观察者来响应来自源Observable的onError通知,而是通过重新订阅源Observable并为其提供另一个机会来完成其序列而不会出现错误。 重试始终将下一个通知传递给其观察者,即使是以错误终止的序列,因此这会导致重复发射
Rx中有几个常见的Catch类的操作符:onErrorReturn,onErrorResumeNext,onExceptionResumeNext。
Rx中也有几个常见的Retry类的操作符:retry,retryWhen。
我们这里来一一看下:
onErrorReturn
指示Observable在遇到错误时发出特定项,然后正常终止。
onErrorReturn运算符,当源Observable发射出onError时,拦截异常并返回一个自定义的值之后正常的结束发射。
举个例子
private void doSomeWork() {
Observable.create(new ObservableOnSubscribe<String>() {
@Override
public void subscribe(ObservableEmitter<String> observableEmitter) throws Exception {
observableEmitter.onNext("1");
observableEmitter.onNext("2");
observableEmitter.onError(new Throwable("error"));
observableEmitter.onNext("3");
observableEmitter.onComplete();
}
}).onErrorReturn(new Function<Throwable, String>() {
@Override
public String apply(Throwable throwable) throws Exception {
Log.d(TAG, " apply : " + throwable.getMessage());
return "onErrorReturn";
}
}).subscribe(new Observer<String>() {
@Override
public void onSubscribe(Disposable disposable) {
}
@Override
public void onNext(String s) {
Log.d(TAG, " onNext : s : " + s);
}
@Override
public void onError(Throwable throwable) {
Log.d(TAG, " onError : " + throwable.getMessage());
}
@Override
public void onComplete() {
Log.d(TAG, " onComplete ");
}
});
}
当源发射2后发射了error,会先触发onErrorReturn里的方法,所以打印了error,onErrorReturn拦截并通过Func返回一个值后正常结束发射,所以打印结果
onNext : s : 1
onNext : s : 2
apply : error
onNext : s : onErrorReturn
onComplete
onErrorResumeNext
源Observable在遇到错误时开始发出第二个Observable序列。
onErrorResumeNext方法与onErrorReturn()方法类似,都是拦截源Observable发射的onError通知。不同的是onErrorReturn拦截并返回一个自定义的值,而onErrorResumeNext拦截并返回一个新的Observable,并继续接收新的Observable发射的数据。
将上方例子稍作更改:
private void doSomeWork() {
Observable.create(new ObservableOnSubscribe<String>() {
@Override
public void subscribe(ObservableEmitter<String> observableEmitter) throws Exception {
observableEmitter.onNext("1");
observableEmitter.onNext("2");
observableEmitter.onError(new Throwable("error"));
observableEmitter.onNext("3");
observableEmitter.onComplete();
}
}).onErrorResumeNext(new Function<Throwable, ObservableSource<? extends String>>() {
@Override
public ObservableSource<? extends String> apply(Throwable throwable) throws Exception {
Log.d(TAG, " apply : " + throwable.getMessage());
return Observable.just("new Observable");
}
}).subscribe(new Observer<String>() {
@Override
public void onSubscribe(Disposable disposable) {
}
@Override
public void onNext(String s) {
Log.d(TAG, " onNext : s : " + s);
}
@Override
public void onError(Throwable throwable) {
Log.d(TAG, " onError : " + throwable.getMessage());
}
@Override
public void onComplete() {
Log.d(TAG, " onComplete ");
}
});
}
打印结果:
onNext : s : 1
onNext : s : 2
apply : error
onNext : s : new Observable
onComplete
onExceptionResumeNext
指示Observable在遇到异常后继续发出项目(但不是另一种类型的throwable)
onExceptionResumeNext和onErrorResumeNext类似,不同的是,onExceptionResumeNext如果onError收到的Throwable不是一个Exception,它会将错误传递给观察者的onError方法,不会使用新的Observable。
举个例子
private void doSomeWork() {
Observable.create(new ObservableOnSubscribe<String>() {
@Override
public void subscribe(ObservableEmitter<String> observableEmitter) throws Exception {
observableEmitter.onNext("1");
observableEmitter.onNext("2");
observableEmitter.onError(new Throwable("error"));
// observableEmitter.onError(new Exception("error"));
observableEmitter.onNext("3");
observableEmitter.onComplete();
}
}).onExceptionResumeNext(Observable.just("new Observable"))
.subscribe(new Observer<String>() {
@Override
public void onSubscribe(Disposable disposable) {
}
@Override
public void onNext(String s) {
Log.d(TAG, " onNext : s : " + s);
}
@Override
public void onError(Throwable throwable) {
Log.d(TAG, " onError : " + throwable.getMessage());
}
@Override
public void onComplete() {
Log.d(TAG, " onComplete ");
}
});
}
onError发射的是个非Exception的Error,onExceptionResumeNext不会使用新的Observable,所以打印结果
onNext : s : 1
onNext : s : 2
onError : error
如果将上方例子中此段代码按如下更改
// observableEmitter.onError(new Throwable("error"));
observableEmitter.onError(new Exception("error"));
onError发射的是个Exception的Error,打印结果
onNext : s : 1
onNext : s : 2
onNext : s : new Observable
onComplete
retry
在遇到错误时应尝试重新订阅源Observable。
retry顾名思义就是重试,遇到Error后让源Observable重新从头发射。
举个例子:
private void doSomeWork() {
Observable.create(new ObservableOnSubscribe<String>() {
@Override
public void subscribe(ObservableEmitter<String> observableEmitter) throws Exception {
observableEmitter.onNext("1");
observableEmitter.onNext("2");
int random = new Random().nextInt(10);
Log.d(TAG, " subscribe : random : " + random);
if (random >= 5)
observableEmitter.onError(new Throwable("error"));
observableEmitter.onNext("3");
observableEmitter.onComplete();
}
}).retry(2)
.subscribe(new Observer<String>() {
@Override
public void onSubscribe(Disposable disposable) {
}
@Override
public void onNext(String s) {
Log.d(TAG, " onNext : s : " + s);
}
@Override
public void onError(Throwable throwable) {
Log.d(TAG, " onError : " + throwable.getMessage());
}
@Override
public void onComplete() {
Log.d(TAG, " onComplete ");
}
});
}
打印结果
onNext : s : 1
onNext : s : 2
subscribe : random : 9
onNext : s : 1
onNext : s : 2
subscribe : random : 8
onNext : s : 1
onNext : s : 2
subscribe : random : 2
onNext : s : 3
onComplete
retryWhen
retryWhen和retry类似, 他的区别根据名字也可以知道,他可以让我们控制当xxx时才重试,retryWhen的参数是个Func,我们可以在里面做逻辑处理,如果需要重试,只需要发射一个正常的项即可触发源Observable重试,否则可以发射Error结束。
举个例子:
private void doSomeWork() {
Observable.create(new ObservableOnSubscribe<String>() {
@Override
public void subscribe(ObservableEmitter<String> observableEmitter) throws Exception {
observableEmitter.onNext("1");
observableEmitter.onNext("2");
int random = new Random().nextInt(10);
Log.d(TAG, " subscribe : random : " + random);
if (random >= 5)
observableEmitter.onError(new Exception("error"));
observableEmitter.onNext("3");
observableEmitter.onComplete();
}
}).retryWhen(new Function<Observable<Throwable>, ObservableSource<?>>() {
@Override
public ObservableSource<?> apply(Observable<Throwable> throwableObservable) throws Exception {
return throwableObservable.flatMap(new Function<Throwable, ObservableSource<?>>() {
@Override
public ObservableSource<?> apply(Throwable throwable) throws Exception {
if (throwable instanceof Exception)
return Observable.just("4");
else
return Observable.just(throwable);
}
});
}
})
.subscribe(new Observer<String>() {
@Override
public void onSubscribe(Disposable disposable) {
}
@Override
public void onNext(String s) {
Log.d(TAG, " onNext : s : " + s);
}
@Override
public void onError(Throwable throwable) {
Log.d(TAG, " onError : " + throwable.getMessage());
}
@Override
public void onComplete() {
Log.d(TAG, " onComplete ");
}
});
}
打印结果
onNext : s : 1
onNext : s : 2
subscribe : random : 5
onNext : s : 1
onNext : s : 2
subscribe : random : 2
onNext : s : 3
onComplete
日常在处理错误异常的时候,我们可能还需要配合do操作符的方法,在某些合适的节点进行处理。这个以后再说吧。