RxJava主题和错误处理

时间:2015-07-29 10:55:12

标签: java android rx-java rx-android

我正在尝试实现类似于事件总线的行为。根据我的要求,PublishSubject似乎合适。

主题会发出表示某些全局操作结果的项目,这些项目可能会成功解析或在发生异常时失败。我无法使用onNext()用于成功事件,onError()可以使用Throwable以防出错,因为一旦onError()被调用,主题就会终止,任何未来的订阅者除onError()之外,不会产生任何排放。

现在我看到它的方式我必须创建一个表示事件的类,并在出现错误时可选地引用Throwable。然而,这似乎是不明智的,因为必须处理onNext()内的错误。

你会怎么做?

1 个答案:

答案 0 :(得分:4)

创建包装事件的通用类是一种方法。假设我们称之为 ResponseOrError 类,它应该基本上包含两个字段

private T data;
private Throwable error;

和两个简单​​的工厂方法:

public static <T> ResponseOrError<T> fromError(Throwable throwable) {
    return new ResponseOrError<>(throwable);
}

public static <T> ResponseOrError<T> fromData(T data) {
    return new ResponseOrError<>(data);
}

删除一些样板代码,您可以提供Transformer以使Observable为ResponseOrError类型。

public static <T> Observable.Transformer<T, ResponseOrError<T>> toResponseOrErrorObservable() {
    return new Observable.Transformer<T, ResponseOrError<T>>() {

        @Override
        public Observable<ResponseOrError<T>> call(final Observable<T> observable) {
            return observable
                    .map(new Func1<T, ResponseOrError<T>>() {
                        @Override
                        public ResponseOrError<T> call(final T t) {
                            return ResponseOrError.fromData(t);
                        }
                    })
                    .onErrorResumeNext(new Func1<Throwable, Observable<? extends ResponseOrError<T>>>() {
                        @Override
                        public Observable<? extends ResponseOrError<T>> call(final Throwable throwable) {
                            return Observable.just(ResponseOrError.<T>fromError(throwable));
                        }
                    });
        }
    };
}

那么你就可以这样使用它:

final Observable<ResponseOrError<ImportantData>> compose = mNetworkService
               .getImportantData()
               .compose(ResponseOrError.<ImportantData>toResponseOrErrorObservable());

现在您可以根据成功或失败轻松映射结果,甚至可以提供另一个 Transformer 返回映射 Observable&lt; T&gt; 而不是 Observable&lt; ResponseOrError&LT; T&GT;&GT;