我正在努力学习如何用RxJava表达以下内容。让我们想象一下,我想要在网络上传输一个数据包流列表:
PublishSubject<List<Packet>> packetsSubject = ...;
我有以下传输功能:
public Observable<Status> transmit(Packet p) {...}
只要数据包的返回状态为Status.OK
,我想传输列表中的每个数据包。换句话说,如果第n个分组的传输是NOK,则不应该发送第n + 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。