RxJava:合并多个单曲并在一些失败后完成

时间:2018-04-11 13:57:14

标签: rx-java2

我想合并两个Single<MyData>,这样如果其中一个失败但另一个失败则报告失败的错误和另一个的错误报告,然后生成{{} 1}}(或Single<MyData>)完成。

如果两个Observable<MyData>都失败,那么结果也会失败并且也会被标记为失败。

我最终想要的是:

  • 如果两者都成功,则发出的值和生产者标记为已完成。
  • 如果一个成功而另一个失败,则发出的值,抛出的错误和生产者标记为完成。
  • 如果全部失败,则错误和生产者标记为失败。

它就像一个&#39; OR&#39;操作

2 个答案:

答案 0 :(得分:0)

这是不可能的。只允许一个终端事件。 Single的合同为success|error。如果您还需要接收下一个活动,则应考虑使用ObservableObservable的合同为next* complete|error,但您仍然无法完成。

Observable.mergeDelayError(single1.toObservable(), single2.toObservable())

答案 1 :(得分:0)

这可以通过Single.create(SingleOnSubscribe)完成。如果您的返回类型为Single<MyData>,则只能返回其中一个响应,但是您也可以对其进行修改,以返回Single<List<MyData>>或其他支持多个返回的RxJava结构,例如Flowable<MyData>。在此示例中,Single<MyData>返回最后一个调用,因为这是最简单的实现。

public Single<MyData> getCombinedSingle(List<Single<MyData>> singles) {
    return Single.create(new SingleOnSubscribe<MyData> {
        private boolean encounteredError = false;
        private MyData myData;

        @Override
        public void subscribe(@NonNull Emitter<MyData> emitter) {
            List<Disposable> disposables = new ArrayList<>();
            Consumer<MyData> myDataConsumer = myData -> {
                this.MyData = myData;
                checkForFinish(emitter, disposables);
            }
            Consumer<Throwable> throwableConsumer = throwable -> {
                throwable.printStackTrace();
                encounteredError = true;
                checkForFinish(emitter, disposables);
            }
            for (Single single: singles) {
                disposables.put(single.subscribe(myDataConsumer, throwableConsumer);
            }
        }

        private void checkForFinish(SingleEmitter<MyData> emitter, List<Disposable> disposables) {
            if (disposables1.stream().allMatch(Disposable::isDisposed)) {
                if (encounteredError) {
                    emitter.onError(new Throwable());
                } else {
                    emitter.onSuccess(myData);
                }
            }
        }
    }
}

如果需要,可以将其修改为从原始Singles返回Throwable。