首页 > 解决方案 > 使用 CompletableFuture 构建具有多种方法的对象

问题描述

我试图了解CompletableFuture以及如何利用它来构建一个包含从多个端点获得的信息的对象。我遇到了一些例子,但没有一个完全适合我的问题。例如,这个并行运行相同的方法来获取一个字符串列表,我想在其中并行运行多个方法来构建和返回一个对象。

我为员工创建了一个简单的 DTO:

@Builder
@Data
@AllArgsConstructor
public class EmployeeDTO {

    private String name;
    private String accountNumber;
    private int salary;

}

我创建了一个服务来模拟对三个单独 API 的调用,以设置 DTO 的值,等待时间相当长:

public class EmployeeService {

    public EmployeeDTO setName() {
        try {
            Thread.sleep(10 * 1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return EmployeeDTO.builder().name("John Doe").build();
    }

    public EmployeeDTO setAccountNumber() {
        try {
            Thread.sleep(10 * 1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return EmployeeDTO.builder().accountNumber("1235").build();
    }

    public EmployeeDTO setSalary() {
        try {
            Thread.sleep(10 * 1000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        return EmployeeDTO.builder().salary(100000).build();
    }
}

我可以supplyAsync使用所有三种方法,然后运行allOf,但它什么也没做:

    private void run() {
        EmployeeService employeeService = new EmployeeService();

        CompletableFuture<EmployeeDTO> employeeCfWithName = CompletableFuture
                .supplyAsync(employeeService::setName);
        CompletableFuture<EmployeeDTO> employeeCfWithAccountNumber = CompletableFuture
                .supplyAsync(employeeService::setAccountNumber);
        CompletableFuture<EmployeeDTO> employeeCfWithSalary = CompletableFuture
                .supplyAsync(employeeService::setSalary);

        CompletableFuture allCompletableFutures = CompletableFuture.allOf(employeeCfWithName, employeeCfWithAccountNumber, employeeCfWithSalary);
    }

如何将结果合并到一个 EmployeeDTO 中?

标签: java

解决方案


您必须将三个CompletableFutures 的结果组合成一个EmployeeDTO. 这不是由allOf.

尝试这样的事情(未经测试):

CompletableFuture allCompletableFutures = CompletableFuture.allOf(
  employeeCfWithName, employeeCfWithAccountNumber, employeeCfWithSalary);

// Wait for all three to complete.
allCompletableFutures.get();

// Now join all three and combine the results.
EmployeeDTO finalResult = EmployeeDTO.builder()
  .name(new employeeCfWithName.join())
  .accountNumber(new employeeCfWithAccountNumber.join())
  .salary(new employeeCfWithSalary.join())
  .build();

这看起来有点傻。我们在每种方法中都使用一个构建器,只是为了使用第四个构建器组合它们的结果。


推荐阅读