java如何执行CompletableFuture函数并得到结果,或者先执行哪一个?
我已经创建了3个函数来执行对数据库的查询,然后我想得到每个结果并将其添加到一个对象列表中,但结果总是空的,我如何才能正确地执行此操作?以下是我的工作:
我创建了3个完整的未来函数:
private CompletableFuture<List<TransSalesOrderOnlyResponseDto>> findPureUnAssignedSO() {
return CompletableFuture.supplyAsync(() -> iSalesOrderMapper.entityToSOOnlyDto(iTransSalesOrderQdslRepository.findUnAssignedSalesOrder()));
}
private CompletableFuture<List<TransSalesOrderOnlyResponseDto>> findSOHaveItemLeftOverOnly() {
return CompletableFuture.supplyAsync(() -> {
List<TransSalesOrder> transSalesOrders = iTransSalesOrderQdslRepository.findSOHaveLeftOverButDone();
return buildTransSalesOrdersResponseNew(transSalesOrders);
});
}
private CompletableFuture<List<TransSalesOrderOnlyResponseDto>> findSalesOrderWithBpsjInDeliveryOrder() {
return CompletableFuture.supplyAsync(() -> {
List<TransSalesOrder> transSalesOrders = iTransSalesOrderQdslRepository.findSalesOrderWithBpsjInDeliveryOrder();
return buildTransSalesOrdersBpsjOnlyResponseNew(transSalesOrders);
});
}
下面是我如何执行这3个函数:
尝试1,使用get():
public List<TransSalesOrderOnlyResponseDto> findUnAssignedSO() {
CompletableFuture<List<TransSalesOrderOnlyResponseDto>> future = new CompletableFuture<>();
List<TransSalesOrderOnlyResponseDto> transSalesOrdersResponseNew = new ArrayList<>();
try {
transSalesOrdersResponseNew = findSOHaveItemLeftOverOnly().get();
transSalesOrdersResponseNew.addAll(findPureUnAssignedSO().get());
transSalesOrdersResponseNew.addAll(findSalesOrderWithBpsjInDeliveryOrder().get());
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
return transSalesOrdersResponseNew;
}
结果仍然是空的
尝试2:
public List<TransSalesOrderOnlyResponseDto> findUnAssignedSO() {
List<TransSalesOrderOnlyResponseDto> transSalesOrdersResponseNew = new ArrayList<>();
CompletableFuture<List<TransSalesOrderOnlyResponseDto>> soHaveItemLeftOverOnly = findSOHaveItemLeftOverOnly();
CompletableFuture<List<TransSalesOrderOnlyResponseDto>> pureUnAssignedSO = findPureUnAssignedSO();
CompletableFuture<List<TransSalesOrderOnlyResponseDto>> salesOrderWithBpsjInDeliveryOrder = findSalesOrderWithBpsjInDeliveryOrder();
CompletableFuture.allOf(soHaveItemLeftOverOnly, pureUnAssignedSO, salesOrderWithBpsjInDeliveryOrder)
.thenRun(() -> {
transSalesOrdersResponseNew.addAll(soHaveItemLeftOverOnly.join());
transSalesOrdersResponseNew.addAll(pureUnAssignedSO.join());
transSalesOrdersResponseNew.addAll(salesOrderWithBpsjInDeliveryOrder.join());
});
}
return transSalesOrdersResponseNew;
}
如果我这样做,结果总是空的,即使我使用。get()要阻止结果,如何正确执行completablefuture
# 1 楼答案
你的两次尝试都不起作用,因为你在没有等待结果的情况下调用了一个完成阶段(不过我不确定尝试1)
我不知道所有方法的签名,但是如果在某处您在
supplyAsync
中返回一个CompletionStage
,并且您没有使用thenCompose
,那么函数将忽略CompletionStage的结果而返回在第二次尝试中,更容易看出错误所在。这一部分:
你在
thenRun
部分做什么并不重要。您不需要在任何地方等待结果,因此它将立即到达return transSalesOrdersResponseNew;
,即使您在thenRun
部分中定义的函数尚未完成假设方法
findSOHaveItemLeftOverOnly
、findPureUnAssignedSO
和findSalesOrderWithBpsjInDeliveryOrder
是正确的(我们无法从您提供的详细信息中知道这一点),您可以这样重写代码:注意,我正在使用
.thenCompose
,这将使用函数的结果作为序列中的下一个CompletionStage
。这样你就不会在过程中失去结果您还可以使用
CompletableFuture.allOf
并行运行find方法(如果顺序不重要),但在这种情况下,您需要确保使用线程安全的List实现。 它看起来是这样的: