代码之家  ›  专栏  ›  技术社区  ›  Peddro

RxJava2 materialize()在发生错误后不发出下一项

  •  0
  • Peddro  · 技术社区  · 8 年前

    我一直在尝试将OneErrors转换为通知,以保持流发出的项目。据我所知,materialize()操作符就是这样做的。所以基本上:

    materialize()/dematerialize()可用于转换终端事件 进入通知

    所以我根据这个问题做了一个测试( How to continue streaming items after error in RxJava? ). 我尝试了以下方法:

     @Test
    public void materializeTest() {
        final Observable<String> stringObservable = Observable.fromArray("1", "2", "3")
                .flatMap(x -> {
                    if (x.equals("2")) {
                        return Observable.error(new NullPointerException());
                    }
    
                    return Observable.just(x);
                })
                .materialize()
                .map(n -> n.getValue());
    
        final TestObserver<String> testObs = stringObservable.test();
        Java6Assertions.assertThat(testObs.values().size()).isEqualTo(2);
    
        testObs.assertValueAt(0, "1");
        testObs.assertValueAt(1, "3");
    }
    

    结果是,在“2”给出错误后,不会发出更多的项。我还尝试在自己的通知对象上进行扭曲( MyNotification<T> )然后做类似的事情:

    stringObs
      .map(string -> MyNotification.success(string)
      .onErrorReturn(error -> MyNotification.error())
    

    但最终的结果总是一样的:在“2”之后,不再发出更多的项目。我百分之百地做错了什么,但我真的不明白是什么。

    1 回复  |  直到 8 年前
        1
  •  1
  •   akarnokd    8 年前

    具有 flatMap ,如果内部 Observable s失败时,序列终止,并且没有从上游转换其他项目。这种情况会发生 之前 materialize() 甚至参与其中。

    因此,与其尝试具体化合并流,不如单独具体化内部源:

    Observable.fromArray("1", "2", "3")
            .flatMap(x -> {
                if (x.equals("2")) {
                    return Observable.<String>error(new NullPointerException())
                                     .materialize();
                }
    
                return Observable.just(x)
                                 .materialize();
            })
            .filter(n -> n.isOnNext())
            .map(n -> n.getValue());