使用RxJava的同步序列

时间:2017-10-18 13:51:50

标签: rx-java rx-java2

我正在努力学习如何用RxJava表达以下内容。让我们想象一下,我想要在网络上传输一个数据包流列表:

PublishSubject<List<Packet>> packetsSubject = ...;

我有以下传输功能:

public Observable<Status> transmit(Packet p) {...}

只要数据包的返回状态为Status.OK,我想传输列表中的每个数据包。换句话说,如果第n个分组的传输是NOK,则不应该发送第n + 1个分组。

此外,如果检测到错误:

  • 应该在列表
  • 中显示包的索引
  • 应该开始传输下一个数据包列表

感谢您阅读我

1 个答案:

答案 0 :(得分:2)

您可以使用flatMap()运算符将列表转换为可观察条目。使用zipWith()运算符将每个列表条目与单个列表中的数据包索引配对。 flatMap()再次传输并获得结果状态。将NOK变为throwable,并终止内部观察链。使用flatMap()运算符时,添加1的最终参数会使映射一次发生一次,因此此观察链中的请求不会重叠。

packetsSubject
      .flatMap( listOfPackets -> Observable.from( listOfPackets )
            .zipWith( Observable.range( 1, LARGE_NUMBER ), ( p, i ) -> new Pair<>( p, i ) )
            .flatMap( pair -> transmits( pair.getFirst() )
                    .flatMap( status -> status.equals( "OK" )
                            ? Observable.empty()
                            : Observable.error( new IllegalStateException() ) )
                    .doOnError( error -> System.out.println( "Error at index " + pair.getSecond() ) )
                    .onErrorResumeNext( Observable.empty() ), 1 ) )
    .subscribe();

虽然我对将NOK映射到错误,记录它,然后重新映射结果的最后内部步骤感到不舒服,但我有理由这样做。 listOfPackets的处理必须在处理完所有数据包或看到Status.NOK时终止;将Status.NOK转换为错误指示符即可实现此目的。但是,我们只希望单个列表的处理终止,而不是整个observable。