可完成的未来内部的可完成的未来

时间:2019-09-18 18:39:54

标签: java-8 completable-future

我的代码中有几个可以完成的未来。在一个可完成的未来中,我想要另一个可完成的未来(在可完成的未来中的可完成的未来),例如

public CompletableFuture<List<Employee>> buildEmployee (List<EmployeeResponse> employeeInfo) {
    return supplyAsync(() -> {

        Map<String, List<EmployeeReward>> rewards = rewards(employeeInfo);
        Map<String, List<EmployeePoints>> points = points(employeeInfo);
    }, executor);
}

在上述方法中,奖励和积分是两个独立的顺序调用,我希望它为我尝试的它们并行调用-

public CompletableFuture<List<Employee>> buildEmployee (List<EmployeeResponse> employeeInfo) {
    return supplyAsync(() -> {

        CompletableFuture<Map<String, List<EmployeeReward>>> rewards = reward(employeeInfo);
        CompletableFuture<Map<String, List<EmployeePoints>>> points = points(employeeInfo);

        CompletableFuture<Void> futures = allOf(rewards, points);
    }, executor);
}
  1. 这样做是正确的方法吗?如果方法不正确,该如何改善?

我正在如下构建<List<Employee>>

employeeInfo.stream.map(employee -> Employee.builder().
  .<someEmplyInfo>
  .points(points.getOrDefault(employee.getEmpId, newArrayList()))
);

2 个答案:

答案 0 :(得分:2)

重要的是要处理个别期货的特殊例外情况。

理想情况下,控制流不应依赖于异常处理逻辑,而应将其包装在状态对象中,该状态对象可用于评估是否应进行进一步处理。 在allOf方法后添加一个thenApply,然后在thenApply块中获取结果应该可以解决问题

public CompletableFuture<List<Employee>> buildEmployee(List<EmployeeResponse> employeeInfo) {
    //Build the future instance for reward
    CompletableFuture<Map<String, List<EmployeeReward>>> rewardsFuture = reward(employeeInfo)
        .exceptionally(throwable -> {
            //Handle the error
            return null;
        });

    //Build the future instance for points
    CompletableFuture<Map<String, List<EmployeePoints>>> pointsFuture = points(employeeInfo)
        .exceptionally(throwable -> {
            //Handle the error for rewards
            return null;
        });

    return CompletableFuture.allOf(rewardsFuture, pointsFuture).thenApply(v -> {
        try {
            Map<String, List<EmployeeReward>> rewardsResult = rewardsFuture.get();
            Map<String, List<EmployeePoints>> pointsResult = pointsFuture.get();

            //Convert the above map to the desired list of string
            List<Employee> buildEmployeeResult = null;
            return buildEmployeeResult;
        }
        catch (Exception e) {
            //Handle exception
            return null;
        }
    }, executor);
}

private CompletableFuture<Map<String, List<EmployeePoints>>> points(List<EmployeeResponse> employeeInfo) {
    return supplyAsync(() -> {
        //Logic for points synchronous
    });
}

private CompletableFuture<Map<String, List<EmployeeReward>>> reward(List<EmployeeResponse> employeeInfo) {
    return supplyAsync(() -> {
        //Logic for rewards synchronous
    });
}

答案 1 :(得分:0)

在上述方法中,您使用Async线程执行buildEmployee方法,这意味着Async线程负责进行两个API调用rewards和{{1}然后合并结果。因此,在上述方法中,该方法是异步执行的,而不是API调用。

但是您可以通过异步进行API调用,使用points异步进行reward调用,然后使用主线程进行supplyAsync调用来实现另一种方式。最后阻塞主线程,直到异步调用完成,然后合并结果

points
相关问题