RxJava Observable 和 Subscriber 用于跳过异常? [英] RxJava Observable and Subscriber for skipping exception?

查看:34
本文介绍了RxJava Observable 和 Subscriber 用于跳过异常?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果我有一个观察者:

List<Integer> ints = Lists.newArrayList(1, 2, 0, 3, 4);
Observable<Integer> o1 = Observable.from(ints);

我想生成另一个 observable ,除以 12 :

I want to generate another observable , which divide by 12 :

Observable<Integer> o2 = o1.map(i -> 12/i);
o2.subscribe(
  v -> logger.info ("Subscriber value {}", v) ,
  t -> logger.error("Subscriber onError {} : {}", t.getClass() , t.getMessage())
);

很明显会报错,遇到'0'就停止:

It's obvious it will got error , and stopped when it encounter '0' :

RxTest - Subscriber value 12
RxTest - Subscriber value 6
RxTest - Subscriber onError class java.lang.ArithmeticException : / by zero

但是如果我想让 Observer(o2) 跳过异常怎么办?

But what if I want the Observer(o2) skip the exception ?

我查看了 RxJava 的关于 错误处理 的文档,没有跳过错误的方法.onErrorResumeNext()onExceptionResumeNext() 需要一个 backup/fallback Observable ,这不是我想要的.onErrorReturn 需要指定返回值.

I look into RxJava's doc about error handling , there is no way to skip the error. The onErrorResumeNext() and onExceptionResumeNext() needs a backup/fallback Observable , which is not what I want. The onErrorReturn need to specify the return value .

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

All three of the error handling methods cannot resume the original observer . for example :

Observable<Integer> o2 = o1.map(i -> 12/i)
      .onErrorReturn(t -> 0);

它打印:

RxTest - Subscriber value 12
RxTest - Subscriber value 6
RxTest - Subscriber value 0

不打印其余的 12/3 和 12/4

Not printing the rest 12/3 and 12/4

唯一的解决方案似乎是在 map 函数中中继:

The only solution seems relay in the map function :

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

它有效,但很麻烦.想知道在操作Observable(比如map)

It works , but it is cumbersome . I wonder if there's any way to easily skip any RuntimeException when manipulating Observable (such as map)

以上是关于在 Observable 中跳过异常.以下是关于跳过 Subscriber 中的异常:

The above is about skipping exception in Observable . The following is about skipping exception in the Subscriber :

情况是一样的:

List<Integer> ints = Lists.newArrayList(1, 2, 0 , 3 , 4);
Observable<Integer> o1 = Observable.from(ints);
o1.subscribe(
  i -> logger.info("12 / {} = {}", i, 12 / i),
  t -> logger.error("{} : {}", t.getClass() , t.getMessage()),
  () -> logger.info("onCompleted")
);

它打印出来:

RxTest - 12 / 1 = 12
RxTest - 12 / 2 = 6
RxTest - class java.lang.ArithmeticException : / by zero

onNext 发生异常时,它会触发 onError ,并且不会响应 Observable 中的任何数据.如果我希望订阅者吞下异常,我必须尝试捕获 onNext() 中的 ArithmeticException .有没有更清洁的解决方案?

When exception occurs in onNext , it triggers onError , and NOT RESPONDING to any data from the Observable . If I want the subscriber to swallow the exception , I have to try-catch the ArithmeticException in the onNext() . Is there any cleaner solution ?

似乎当 SubscriberonNext() 中遇到无法在 (onNext) 内处理的错误时,它应该停止,正确的 ?这是一个好的设计吗?

It seems when a Subscriber faces an error in the onNext() that cannot be handled within (onNext) , it shall stop , right ? Is it a good design ?

推荐答案

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

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

it's one way to go, though keep in mind that RxJava assumes that error is something truly unexcpeted (you can expect values to be 0). On the other hand, if you want to ignore divide by 0 exception maybe you should filter/map your values before division.

这篇关于RxJava Observable 和 Subscriber 用于跳过异常?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆