如何在RxJava中从错误中恢复时处理不同的流?

时间:2017-05-15 21:12:12

标签: rx-java

我有一个rx流,可能会在早期运算符中产生错误。如果发生此错误,我可以恢复,但恢复"路径"不再发出与"快乐路径相同的类型项目"。处理这种情况的最佳方法是什么?

举个例子。让我们说我的第一个map通常会发出Integer。它有时也抛出MyException。我可以从此错误中恢复,但我开始发布MyObject而不是Integer的新路径。

public void main() {
    Observable.just(1, 2, 3, 4, 5)
              .map(integer -> { // double
                  if (integer == 3) {
                      throw new MyException();
                  }
                  return integer * 2;
              })
              .onErrorResumeNext(new Func1<Throwable, Observable<? extends Integer>>() {
                  @Override
                  public Observable<? extends Integer> call(Throwable throwable) {
                      if (throwable instanceof MyException) {
                          // recover from MyException,
                          // but I start down a new path that doesn't emit an Integer
                          return Observable.just(true)
                                           .map((Func1<Boolean, MyObject>) aBoolean -> new MyObject());
                      } else { // just propagate all other errors
                          return Observable.error(throwable);
                      }
                  }
              })
              .map(integer -> "(╯°□°)╯︵ ┻━┻ " + integer.toString()) // table flip
              .subscribe(
                      System.out::println, // on next
                      throwable -> {
                          if (throwable instanceof MyException) {
                              // not possible, since I recovered from MyException
                          }
                          System.out.println("error: " + throwable.getMessage());
                      },
                      () -> System.out.println("stream completed"));
}

private class MyException extends RuntimeException {}
private class MyObject {}

2 个答案:

答案 0 :(得分:2)

在这种情况下,groupBy运营商可能会提供帮助。看看这个答案,看看它是否对您有所帮助https://stackoverflow.com/a/30120775/1830141

答案 1 :(得分:1)

您可以在onErrorResumeNext()调用之前移动第二个映射。如果使用映射的公共超类型和 next 值(在示例中为Object),则可以将这两个值传播到订阅者并在那里正确处理。

Observable
    .<Integer>just(...)
    .<Integer>map(...)
    .<Object>map(...)
    .onErrorResumeNext(new Func1<Throwable, Observable<? extends Object>>() {
         @Override
         public Observable<? extends Integer> call(Throwable throwable) {
             if (throwable instanceof MyException) {
                 return Observable.just(true)
                            .<MyObject>map(aBoolean -> new MyObject());
             } else {
                 return Observable.error(throwable);
             }
         }
     })
    .subscribe(...);