为了账号安全,请及时绑定邮箱和手机立即绑定

使用 CompletableFuture 构建具有多种方法的对象

使用 CompletableFuture 构建具有多种方法的对象

ibeautiful 2023-05-10 14:09:41
我正在尝试了解CompletableFuture以及如何利用它来构建一个包含从多个端点获得的信息的对象。我遇到过几个例子,但没有一个是完全适合我的问题的。例如,这个并行运行相同的方法来获取字符串列表,我想在其中并行运行多个方法来构建和返回一个对象。我为员工创建了一个简单的 DTO:@Builder@Data@AllArgsConstructorpublic 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?
查看完整描述

2 回答

?
www说

TA贡献1775条经验 获得超8个赞

您必须将三个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();

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


查看完整回答
反对 回复 2023-05-10
?
茅侃侃

TA贡献1842条经验 获得超21个赞

让您的员工服务函数将EmployeeDTO.builder()作为输入,然后在 run() 函数中创建一个构建器,并在所有 supplyAsync 调用中将该构建器传递给服务。还要确保在调用 allOf() 之后调用 build() ,这保证了每个服务调用都完成了它的一部分。也不要内置单独的服务功能 -


public class EmployeeService {


    public EmployeeDTO setName(EmployeeDTO.EmployeeDTOBuilder builder) {

        try {

            Thread.sleep(10 * 1000);

        } catch (InterruptedException e) {

            e.printStackTrace();

        }

        return builder.name("John Doe");

    }


    public EmployeeDTO setAccountNumber(EmployeeDTO.EmployeeDTOBuilder builder) {

        try {

            Thread.sleep(10 * 1000);

        } catch (InterruptedException e) {

            e.printStackTrace();

        }

        return builder.accountNumber("1235");

    }


    public EmployeeDTO setSalary(EmployeeDTO.EmployeeDTOBuilder builder) {

        try {

            Thread.sleep(10 * 1000);

        } catch (InterruptedException e) {

            throw new RuntimeException(e);

        }

        return builder.salary(100000);

    }

}

private void run() {

        EmployeeService employeeService = new EmployeeService();


        EmployeeDTO.EmployeeDTOBuilder builder = EmployeeDTO.builder();


        CompletableFuture<EmployeeDTO> employeeCfWithName = CompletableFuture

                .supplyAsync(()-> emoplyeeService.setName(builder));

        CompletableFuture<EmployeeDTO> employeeCfWithAccountNumber = CompletableFuture

                .supplyAsync(()-> emoplyeeService.setAccount(builder));

        CompletableFuture<EmployeeDTO> employeeCfWithSalary = CompletableFuture

                .supplyAsync(()-> emoplyeeService.setSalary(builder));


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


        builder.build();

    }


查看完整回答
反对 回复 2023-05-10
  • 2 回答
  • 0 关注
  • 80 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信