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(_))