Java 反应器:以非阻塞方式重新写入do while循环
我不熟悉反应式编程,并尝试将此方法重新编写为非阻塞方式Java 反应器:以非阻塞方式重新写入do while循环,java,project-reactor,Java,Project Reactor,我不熟悉反应式编程,并尝试将此方法重新编写为非阻塞方式 //原始代码 专用流量FindAllCurrenTorOrderInternal(最终字符串appKey,最终字符串sessionToken, 最终参数StCurrentOrdersTo操作参数){ 布尔hasMoreOrders=true; 最终列表顺序=新的ArrayList(); 做{ 最终参数ListCurrentOrdersDto下一个操作参数= ParamsListCurrentOrdersTo.from(操作参数) .from
//原始代码
专用流量FindAllCurrenTorOrderInternal(最终字符串appKey,最终字符串sessionToken,
最终参数StCurrentOrdersTo操作参数){
布尔hasMoreOrders=true;
最终列表顺序=新的ArrayList();
做{
最终参数ListCurrentOrdersDto下一个操作参数=
ParamsListCurrentOrdersTo.from(操作参数)
.fromRecord(orders.size())
.build();
最终CurrentOrderSummary报告发送至下一个TorderSummary报告=
listCurrentOrders(appKey、sessionToken、nextOperationParams).block();
orders.addAll(nextOrderSummaryReport.currentOrders());
hasMoreOrders=nextOrderSummaryReport.moreAvailable();
}while(hasMoreOrders);
返回流量。从可计算(订单);
}
问题是,我需要上一次调用的结果,在该调用中,我获取返回项目的数量,并使用它们计算下一个偏移量。
我的方法之一是生成“固定大小”页面参数,并检查是否仍有一些订单要加载:
返回通量
.生成(()->buildNextParam(操作参数,0,最大当前订单数,计数页),(状态,接收器)->{
下一个(州);
返回buildNextParam(operationParams,state.fromRecord()+最大当前订单数计数页,
最大(当前订单数量页面);
})
.map(ParamsListCurrentOrdersDTO.class::cast)
.concatMap(nextParams->listCurrentOrders(appKey、sessionToken、nextParams))
.takeUntil(sum->!sum.moreavable())
.flatMapIterable(CurrentOrderSummaryReportDTO::currentOrders);
此解决方案的问题是,如果第三方服务listCurrentOrders
出于任何原因返回的项目少于MAX\u CURRENT\u ORDERS\u COUNT\u PAGE
以及属性moreavable==true
,则我可能会错过一些项目。因此,我需要知道返回的项目数才能正确构建偏移量。
有什么想法吗
更新
我能够通过引入一个外部偏移计数器来解决这个问题
private Flux<CurrentOrderSummaryDTO> findAllCurrentOrdersInternal(final String appKey, final String sessionToken,
final ParamsListCurrentOrdersDTO operationParams) {
return Flux.defer(() -> {
final AtomicInteger offset = new AtomicInteger();
return Flux
.generate(sink -> sink.next(0))
.concatMap(
unused -> listCurrentOrders(appKey, sessionToken,
buildNextParam(operationParams, offset.get())))
.doOnNext(report -> offset.addAndGet(report.currentOrders()
.size()))
.takeUntil(report -> !report.moreAvailable())
.flatMapIterable(CurrentOrderSummaryReportDTO::currentOrders);
});
专用流量findAllCurrentOrdersInternal(最终字符串appKey,最终字符串sessionToken,
最终参数StCurrentOrdersTo操作参数){
返回流量延迟(()->{
最终AtomicInteger偏移量=新的AtomicInteger();
回流通量
.generate(sink->sink.next(0))
.concatMap(
未使用->列表当前订单(appKey、sessionToken、,
buildNextParam(operationParams,offset.get()))
.doOnNext(报表->偏移量.addAndGet(报表.currentOrders())
.size())
.takeUntil(report->!report.moreAvailable())
.flatMapIterable(CurrentOrderSummaryReportDTO::currentOrders);
});
但这当然引入了副作用代码,但找不到更好的解决方案。为什么?你的代码有什么问题?@Marqueisoflorne你是说这个“副作用”代码有什么问题吗?它不应该是“错误的”从结果的角度来看。但是引入一个副作用操作是一个糟糕的方法。你可以将
原子整数
+通量
包装在通量中。延迟
,至少防止在同一通量
上进行两次订阅时共享状态。为什么?你得到的有什么问题吗?@marqueisoflorne你是指我说的吗这个“副作用”代码有什么问题?从结果的角度来看,它不应该是“错误的”。但是引入副作用操作是一种不好的方法。你可以将原子整数
+通量
包装在通量中。延迟
,至少防止在同一通量上进行两次订阅时共享状态