我最近开始在我的一个项目中使用RxJava2,目前正在致力于在其中实现错误处理。
我在下面编写了一个模拟类,在其中将错误包装到自定义异常中后,最初会引发该错误。但是,我遇到了一些有关stackoverflow错误处理的示例,而其他站点则改用Single.error
。
我使用了两种方法,它们导致我的订户onError
方法被调用,并带有/ by zero
异常。我没有注意到两者之间的任何区别。
Error Handling和Error Handling Operators上有全面的文档,还有许多其他有关如何在引发异常后处理异常的文章。但是javadoc中Single.error和Observable.error的信息非常少。
使用Single.error
或Observable.error
是否比仅引发异常有优势?我们何时选择一种方法而不是另一种方法?
public class Test {
public static void main(String[] args){
Single.just(1)
.flatMap(x -> externalMethod(x))
.subscribe(
s -> System.out.println("Success : " + s),
e -> System.out.println("Error : "+e)
);
}
public static Single<Integer> externalMethod(int x){
int result = 0;
try{
/* Some database / time consuming logic */
result = x % 0;
}
catch (Exception e){
throw new CustomException(e.getMessage()); // --> APPROACH 1
OR
return Single.error(new CustomException(e.getMessage())); // --> APPROACH 2
}
return Single.just(result);
}
}
实际上没关系,因为RxJava尝试捕获并中继所有Throwables
方法1-抛出新的CustomException();(io.reactivex.internal.operators.single.SingleFlatMap)
@Override
public void onSuccess(T value) {
SingleSource<? extends R> o;
try {
o = ObjectHelper.requireNonNull(mapper.apply(value), "The single returned by the mapper is null");
} catch (Throwable e) {
Exceptions.throwIfFatal(e);
downstream.onError(e);
return;
}
if (!isDisposed()) {
o.subscribe(new FlatMapSingleObserver<R>(this, downstream));
}
}
[您会在此处看到,使用try-catch调用flatMap中的给定映射器。如果映射器抛出Throwable,则Throwable将通过onError转发给下游订户。
方法2-返回Single.error(...)(io.reactivex.internal.operators.single.SingleError)
单个错误
@Override
protected void subscribeActual(SingleObserver<? super T> observer) {
Throwable error;
try {
error = ObjectHelper.requireNonNull(errorSupplier.call(), "Callable returned null throwable. Null values are generally not allowed in 2.x operators and sources.");
} catch (Throwable e) {
Exceptions.throwIfFatal(e);
error = e;
}
EmptyDisposable.error(error, observer);
}
public static void error(Throwable e, SingleObserver<?> observer) {
observer.onSubscribe(INSTANCE);
observer.onError(e);
}
单个#error通过#onError在订阅时发出给定的Throwable
当将值发送到Single#flatMap时,将应用映射器,并打开一个订阅,从映射器返回值。
(io.reactivex.internal.operators.single.SingleFlatMap.SingleFlatMapCallback.FlatMapSingleObserver)
@Override
public void onSubscribe(final Disposable d) {
DisposableHelper.replace(parent, d);
}
@Override
public void onError(final Throwable e) {
downstream.onError(e);
}
返回的Single返回Single#error,它通过#onError发出Throwable。给定的#onError将通过onError委托给下游订户。
在性能方面,一个可能比另一个更快,但是必须进行测量才能获得准确的图像。返回Single#error会执行更多分配,并且在Stack(subscribeActual)上具有更多方法。另一方面,投掷Throwable时,必须抓住并对其进行处理。
因此,我认为无论您使用一个还是另一个都无所谓。