簡體   English   中英

RxJava Observable和Subscriber用於跳過異常?

[英]RxJava Observable and Subscriber for skipping exception?

如果我有一個Observalbe:

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

我想生成另一個可觀察的,除以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'時停止:

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

但是,如果我希望Observer(o2)跳過異常呢?

我查看了RxJava關於錯誤處理的文檔,沒有辦法跳過錯誤。 onErrorResumeNext()onExceptionResumeNext()需要一個備份/回退 Observable ,這不是我想要的。 onErrorReturn需要指定返回值。

所有三種錯誤處理方法都無法恢復原始觀察者。 例如 :

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

唯一的解決方案似乎是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());

它有效,但很麻煩。 我想知道在操作Observable時是否有任何方法可以輕松跳過任何RuntimeException (例如map

以上是關於在Observable跳過異常的問題。 以下是關於在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 ,而不會onNext來自Observable任何數據。 如果我希望訂閱者吞下異常,我必須嘗試捕獲onNext()ArithmeticException 有沒有更清潔的解決方案?

SubscriberonNext()中面臨一個無法在( onNext )內處理的錯誤時,它會停止,對嗎? 這是一個好的設計嗎?

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

這是一種方法,但請記住,RxJava假定錯誤是真正無法解決的(您可以預期值為0)。 另一方面,如果你想忽略除以0異常,你可能應該在除法之前過濾/映射你的值。

試試這種方式。

Observable<Integer> o2 = o1.map(i -> 12/i).onErrorFlatMap(e -> Observable.empty());

在上面的代碼中,錯誤事件被空流替換,原始流正在恢復。 因此會跳過錯誤。

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM