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你是指我说的吗这个“副作用”代码有什么问题?从结果的角度来看,它不应该是“错误的”。但是引入副作用操作是一种不好的方法。你可以将
原子整数
+
通量
包装在
通量中。延迟
,至少防止在同一
通量上进行两次订阅时共享状态