Java 如何执行CompletableFuture函数并得到结果,或者先执行哪一个?

Java 如何执行CompletableFuture函数并得到结果,或者先执行哪一个?,java,spring-boot,asynchronous,completable-future,Java,Spring Boot,Asynchronous,Completable Future,我已经创建了3个函数来执行对数据库的查询,然后我想得到每个结果并将其添加到一个对象列表中,但结果总是空的,我如何才能正确地执行此操作?以下是我的工作: 我创建了3个完整的未来函数: private CompletableFuture<List<TransSalesOrderOnlyResponseDto>> findPureUnAssignedSO() { return CompletableFuture.supplyAsync(() -> iSalesOr

我已经创建了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); 
    });
}
private CompletableFuture findPureUnAssignedSO(){
返回CompletableFuture.SupplySync(()->iSalesOrderMapper.EntityToSonlyDTO(iTransSalesOrderQdslRepository.FindAssignedSalesOrder());
}
私有CompletableFuture findSOHaveItemLeftOverOnly(){
返回CompletableFuture.SupplySync(()->{
List transSalesOrders=iTransSalesOrderQdslRepository.FindSoHaveLeftOverButton();
返回buildTransSalesOrdersResponseNew(transSalesOrders);
});
}
私有CompletableFuture findSalesOrderWithBpsjInDeliveryOrder()的{
返回CompletableFuture.SupplySync(()->{
List transSalesOrders=iTransSalesOrderQdslRepository.findSalesOrderWithBpsjInDeliveryOrder();
返回buildTransSalesOrdersBpsjOnlyResponseNew(transSalesOrders);
});
}
下面是我如何执行这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); 
    });
}
尝试1,使用get():

公共列表findunsignedso(){
CompletableFuture=新的CompletableFuture();
List transSalesOrdersResponseNew=new ArrayList();
试一试{
transSalesOrdersResponseNew=findSOHaveItemLeftOverOnly().get();
transSalesOrdersResponseNew.addAll(findPureUnAssignedSO().get());
transSalesOrdersResponseNew.addAll(findSalesOrderWithBpsjInDeliveryOrder().get());
}捕获(中断异常|执行异常e){
e、 printStackTrace();
}
返回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;
}
公共列表findunsignedso(){
List transSalesOrdersResponseNew=new ArrayList();
CompletableFuture soHaveItemLeftOverOnly=findSOHaveItemLeftOverOnly();
CompletableFuture pureUnAssignedSO=findPureUnAssignedSO();
Completable Future salesOrderWithBpsjInDeliveryOrder=findSalesOrderWithBpsjInDeliveryOrder();
CompletableFuture.allOf(仅限soHaveItemLeftOverOnly、pureUnAssignedSO、带BPSjindeliveryOrder的销售订单)
.然后运行(()->{
transSalesOrdersResponseNew.addAll(soHaveItemLeftOverOnly.join());
transSalesOrdersResponseNew.addAll(pureUnAssignedSO.join());
transSalesOrdersResponseNew.addAll(salesOrderWithBpsjInDeliveryOrder.join());
});
}
返回transSalesOrdersResponseNew;
}

如果我这样做,结果总是空的,即使我使用.get()来阻止结果,如何正确地执行completablefuture?

您的两次尝试都不起作用,因为您在不等待结果的情况下调用了一个完成阶段(但我不确定尝试编号1)

我不知道所有方法的签名,但是如果您在某个地方返回
supplyAsync
中的
CompletionStage
,而不使用
thencomose
,则函数将忽略CompletionStage的结果而返回

在第二次尝试中,更容易看出错误所在。这一部分:

CompletableFuture.allOf(...).thenRun(() -> ...);
然后运行
部分中执行什么操作并不重要。您不必在任何地方等待结果,因此它将进入
return transsalesfordersresponsenew立即执行,即使您在
thenRun
部分中定义的函数尚未完成

假设方法
findSOHaveItemLeftOverOnly
findPureUnAssignedSO
findSalesOrderWithBpsjInDeliveryOrder
是正确的(我们无法从您使用的详细信息中知道这一点),您可以通过以下方式重写代码:

final List<TransSalesOrderOnlyResponseDto> transSalesOrdersResponseNew = ... ;

findSOHaveItemLeftOverOnly()
   .thenAccept( transSalesOrdersResponseNew::addAll )
   .thenCompose( v -> findPureUnAssignedSO() )
   .thenAccept( transSalesOrdersResponseNew::addAll )
   .thenCompose( v -> findSalesOrderWithBpsjInDeliveryOrder() )
   .thenAccept( transSalesOrdersResponseNew::addAll )
   .join();

return transSalesOrdersResponseNew;

你的两次尝试都不起作用,因为你在没有等待结果的情况下调用了一个完成阶段(但我不确定尝试1)

我不知道所有方法的签名,但是如果您在某个地方返回
supplyAsync
中的
CompletionStage
,而不使用
thencomose
,则函数将忽略CompletionStage的结果而返回

在第二次尝试中,更容易看出错误所在。这一部分:

CompletableFuture.allOf(...).thenRun(() -> ...);
然后运行
部分中执行什么操作并不重要。您不必在任何地方等待结果,因此它将进入
return transsalesfordersresponsenew立即执行,即使您在
thenRun
部分中定义的函数尚未完成

假设方法
findSOHaveItemLeftOverOnly
findPureUnAssignedSO
findSalesOrderWithBpsjInDeliveryOrder
是正确的(我们无法从您使用的详细信息中知道这一点),您可以通过以下方式重写代码:

final List<TransSalesOrderOnlyResponseDto> transSalesOrdersResponseNew = ... ;

findSOHaveItemLeftOverOnly()
   .thenAccept( transSalesOrdersResponseNew::addAll )
   .thenCompose( v -> findPureUnAssignedSO() )
   .thenAccept( transSalesOrdersResponseNew::addAll )
   .thenCompose( v -> findSalesOrderWithBpsjInDeliveryOrder() )
   .thenAccept( transSalesOrdersResponseNew::addAll )
   .join();

return transSalesOrdersResponseNew;

我刚刚意识到,您可以使用方法引用,他认为这种方法应该有效,因为我刚刚收到错误org.hibernate.LazyInitializationException:未能延迟初始化角色集合:com.bit.microservices.b2b.warehouse.entity.TransSalesOrder.transDeliveryOrder,无法初始化代理-无会话,不过,我应该先用谷歌搜索一下,这个错误与问题无关。无论如何,我已经在我的答案中添加了一些细节,试图解释为什么你使用的其他方法不起作用。请记住,如果答案对你提出的问题是正确的,那么请接受答案。请确保,解释得很好,并且它起作用,谢谢你大卫。我刚刚意识到你可以使用方法引用,他认为这种方法应该有效,因为我刚刚收到错误org.hibernate.LazyInitializationException:未能懒洋洋地初始化角色集合:com.bit.microservices.b2b.warehouse.entity.TransSalesOrder.transDeliveryOrder,无法初始化代理-没有会话,我应该先用谷歌搜索该错误与问题无关。无论如何,我已经在我的答案中添加了一些细节,试图解释为什么其他应用程序