RxJava可观察和订阅服务器是否跳过异常?

RxJava可观察和订阅服务器是否跳过异常?,java,reactive-programming,rx-java,Java,Reactive Programming,Rx Java,如果我有一个观察者: List<Integer> ints = Lists.newArrayList(1, 2, 0, 3, 4); Observable<Integer> o1 = Observable.from(ints); 但是如果我想让观察者(o2)跳过这个异常呢 我查看了RxJava的文档,关于,没有办法跳过这个错误。onErrorResumeNext()和onExceptionResumeNext()需要一个备份/回退可观察的,这不是我想要的。onError

如果我有一个观察者:

List<Integer> ints = Lists.newArrayList(1, 2, 0, 3, 4);
Observable<Integer> o1 = Observable.from(ints);
但是如果我想让观察者(o2)跳过这个异常呢

我查看了RxJava的文档,关于,没有办法跳过这个错误。
onErrorResumeNext()
onExceptionResumeNext()
需要一个备份/回退
可观察的
,这不是我想要的。
onErrorReturn
需要指定返回值

所有三种错误处理方法都无法恢复原始观察者。例如:

Observable<Integer> o2 = o1.map(i -> 12/i)
      .onErrorReturn(t -> 0);
未打印其余12/3和12/4

唯一的解决方案似乎是在
map
功能中进行中继:

Observable<Integer> o2 = o1.map(i -> {
  try {
    return Optional.of(12/i);
  } catch (ArithmeticException e) {
    return Optional.empty();
  }
}).filter(Optional::isPresent)
  .map(o -> (Integer) o.get());
它打印出:

RxTest - 12 / 1 = 12
RxTest - 12 / 2 = 6
RxTest - class java.lang.ArithmeticException : / by zero
当异常发生在
onNext
中时,它会触发
onError
,并且不会响应
可观察的
中的任何数据。如果我想让订阅者接受异常,我必须尝试在
onNext()
中捕获
arithmetricexception
。有没有更干净的解决办法

当订户
onNext()中遇到无法在(
onNext
中处理的错误时,它应该停止,对吗?这是一个好的设计吗?

试试这个方法

Observable<Integer> o2 = o1.map(i -> 12/i).onErrorFlatMap(e -> Observable.empty());
Observable o2=o1.map(i->12/i).onErrorFlatMap(e->Observable.empty());
在上面的代码中,错误事件被一个空流替换,原始流正在恢复。因此,将跳过错误

Observable.just(1, 2, 3, 0, 4)
            .flatMap(i -> Observable.defer(() -> Observable.just(12 / i))
                    .onErrorResumeNext(Observable.just(0)));

这是一种方法,但请记住RxJava假定错误是真正未实现的(您可以期望值为0)。另一方面,如果你想忽略除法0异常,也许你应该在除法之前过滤/映射你的值

在我看来,
onNext()
相当于
Iterator.next()
——当迭代集合时出现问题——抛出异常,迭代器退出(它不会“恢复”迭代)——例如,请参阅。这和我们这里的行为是一样的。这就是说,@benjchristensen可能能够对这个问题有更多的了解。
可选的
映射可能是我最喜欢的处理方法。这非常清楚,而且过滤器很好地处理事件。这是一个很好的封装方式。我会在scala中使用
Try
输入,然后进行过滤。哦,对不起,我没有注意到这个版本。但是可以使用
物化
非物化
来实现
onErrorFlatMap
-类似的组合器,虽然有点困难。我也很好奇,为什么这种方法会在1.0中消失。我唯一要改变的是
可观察。从(1,2,3,0,4)
可观察。只是(1,2,3,0,4)
,因为在1.0.0中,它不会使用
中的
进行编译。
import rx.lang.scala._

import scala.concurrent.duration.DurationDouble
import scala.util.{Failure, Success, Try}

val o1 = List(1, 2, 3, 0, 4) toObservable
val o2 = List(1, 2, 3, 4, 5) toObservable

val o3 = o1 zip o2 map {case (i1, i2) => i2 / i1 } // this will trigger a division by 0 error

val o4 = o3 lift {  
      subscriber: Subscriber[Try[Int]] => new Subscriber[Int](subscriber) {
        override def onNext(v: Int) {
          if (!subscriber.isUnsubscribed)
            subscriber.onNext(Success(v))
        }

        override def onError(e: Throwable) {
          if (!subscriber.isUnsubscribed)
            subscriber.onNext(Failure(e))
        }

        override def onCompleted() {
          if (!subscriber.isUnsubscribed)
            subscriber.onCompleted()
        }
      }
    }

o4 subscribe(println(_))
RxTest - 12 / 1 = 12
RxTest - 12 / 2 = 6
RxTest - class java.lang.ArithmeticException : / by zero
Observable<Integer> o2 = o1.map(i -> 12/i).onErrorFlatMap(e -> Observable.empty());
Observable.just(1, 2, 3, 0, 4)
            .flatMap(i -> Observable.defer(() -> Observable.just(12 / i))
                    .onErrorResumeNext(Observable.just(0)));
import rx.lang.scala._

import scala.concurrent.duration.DurationDouble
import scala.util.{Failure, Success, Try}

val o1 = List(1, 2, 3, 0, 4) toObservable
val o2 = List(1, 2, 3, 4, 5) toObservable

val o3 = o1 zip o2 map {case (i1, i2) => i2 / i1 } // this will trigger a division by 0 error

val o4 = o3 lift {  
      subscriber: Subscriber[Try[Int]] => new Subscriber[Int](subscriber) {
        override def onNext(v: Int) {
          if (!subscriber.isUnsubscribed)
            subscriber.onNext(Success(v))
        }

        override def onError(e: Throwable) {
          if (!subscriber.isUnsubscribed)
            subscriber.onNext(Failure(e))
        }

        override def onCompleted() {
          if (!subscriber.isUnsubscribed)
            subscriber.onCompleted()
        }
      }
    }

o4 subscribe(println(_))