RxJava - 使用 Single.Error / Observable.error 与抛出异常

RxJava - Using Single.Error / Observable.error vs throwing exception

我最近开始在我的一个项目中使用 RxJava2,目前我正致力于在其中实现错误处理。

我在下面编写了一个模拟 class,其中我最初在将错误包装在自定义异常中后抛出错误。但是,我在 Whosebug 和其他站点上遇到的一些错误处理示例使用了 Single.error

我使用了这两种方法,它们导致我的订阅者 onError 方法被调用时出现 / by zero 异常。我没有注意到两者之间有任何区别。

关于 Error Handling and Error Handling Operators along with a lot of other articles on how to handle the exception after it is thrown. But the information in the javadoc for Single.error and Observable.error 的综合文档非常少。

使用 Single.errorObservable.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

APPROACH 1 -- throw new 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));
        }
    }

你在这里看到,来自 flatMap 的给定映射器是通过 try-catch 调用的。如果映射器抛出一个 Throwable,Throwable 将通过 onError 转发给下游订阅者。

APPROACH 2 -- return 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);
}

Single#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 returns 一个 Single#error,它通过 #onError 发出一个 Throwable。给定#onError 将通过onError 委托给下游订阅者。

在性能方面,一个可能比另一个更快,但这必须经过测量才能获得准确的图像。返回 Single#error 会进行更多分配,并在 Stack (subscribeActual) 上有更多方法。另一方面,当抛出一个 Throwable 时,它​​必须被抓住并处理。

因此在我看来,无论您使用一个还是另一个,实际上都没有关系。