Java 8 组合多重可完成期货

Java 8 组合多重可完成期货,java-8,completable-future,Java 8,Completable Future,我有以下组成部分: private JobInfo aggregateJobInfo() { final JobsResult jobsResult = restClient().getJobs(); final List<String> jobIds = extractJobIds(jobsResult); //fetch details, exceptions and config for each job final List<JobDe

我有以下组成部分:

private JobInfo aggregateJobInfo() {
    final JobsResult jobsResult = restClient().getJobs();
    final List<String> jobIds = extractJobIds(jobsResult);

    //fetch details, exceptions and config for each job
    final List<JobDetails> jobDetails = jobIds.stream().map(jobId -> {
        final JobDetailResult jobDetailResult = restClient().getJobDetails(jobId);
        final JobExceptionsResult jobExceptionsResult = restClient().getJobExceptions(jobId);
        final JobConfigResult jobConfigResult = restClient().getJobConfig(jobId);
        return new JobDetails(jobDetailResult, jobExceptionsResult, jobConfigResult);
    }).collect(Collectors.toList());
    return new JobInfo(jobsResult, jobDetails);
}

private static List<String> extractJobIds(final JobsResult jobsResult) {
    final ArrayList<String> jobIds = new ArrayList<>();
    jobIds.addAll(jobsResult.getRunning());
    jobIds.addAll(jobsResult.getFinished());
    jobIds.addAll(jobsResult.getCanceled());
    jobIds.addAll(jobsResult.getFailed());
    return jobIds;
}
private JobInfo aggregateJobInfo(){
final JobsResult JobsResult=restClient().getJobs();
最终列表jobIds=提取jobIds(jobsResult);
//获取每个作业的详细信息、异常和配置
最终列表jobDetails=jobIds.stream().map(jobId->{
最终JobDetailResult JobDetailResult=restClient().getJobDetails(jobId);
最终JobExceptionsResult JobExceptionsResult=restClient().getJobExceptions(jobId);
最终JobConfigResult JobConfigResult=restClient().getJobConfig(jobId);
返回新的JobDetails(jobDetailResult、jobExceptionsResult、jobConfigResult);
}).collect(Collectors.toList());
返回新的JobInfo(jobsResult、jobDetails);
}
私有静态列表extractJobIds(最终JobsResult JobsResult){
final ArrayList jobIds=new ArrayList();
addAll(jobsResult.getRunning());
jobIds.addAll(jobsResult.getFinished());
jobIds.addAll(jobsResult.getcancelled());
jobIds.addAll(jobsResult.getFailed());
返回工单;
}
它只是调用一些端点并聚合一些数据。现在我正试图通过使用CompletableFutures来实现非阻塞,这是我以前没有真正使用过的

private CompletableFuture<JobInfo> aggregateJobInfo() {
    final CompletableFuture<JobsResult> jobsResultFuture = restClient().getJobs();
    final CompletableFuture<List<String>> jobIdsFuture = jobsResultFuture.thenApply(JobInfoCollector::extractJobIds);

     //fetch details, exceptions and config for each job
    final CompletableFuture<List<CompletableFuture<JobDetails>>> jobDetailsFuture = jobIdsFuture.thenApply(jobIds -> {
        return jobIds.stream().map(jobId -> {
            final CompletableFuture<JobDetailResult> jobDetailsResultFuture = restClient().getJobDetails(jobId);
            final CompletableFuture<JobExceptionsResult> jobExceptionsFuture = restClient().getJobExceptions(jobId);
            final CompletableFuture<JobConfigResult> jobConfigFuture = restClient().getJobConfig(jobId);
            return jobDetailsResultFuture.thenCompose(jobDetailResult -> {
                return jobExceptionsFuture.thenCombine(jobConfigFuture, (jobExceptionsResult, jobConfigResult) -> {
                    return new JobDetails(jobDetailResult, jobExceptionsResult, jobConfigResult);
                });
            });

        }).collect(Collectors.toList());
    });
    return null;
private CompletableFuture aggregateJobInfo(){
最终CompletableFuture作业ResultFuture=restClient().getJobs();
final CompletableFuture-jobIdsFuture=jobsResultFuture.thenApply(JobInfoCollector::extractJobIds);
//获取每个作业的详细信息、异常和配置
final Completable Future JobDetails Future=jobIdsFuture。然后应用(jobIds->{
返回jobIds.stream().map(jobId->{
最终CompletableFuture jobDetailsResultFuture=restClient().getJobDetails(jobId);
最终CompletableFuture jobExceptionsFuture=restClient().getJobExceptions(jobId);
最终CompletableFuture jobConfigFuture=restClient().getJobConfig(jobId);
返回jobDetailsResultFuture.thenCompose(JobDetailsResult->{
返回jobExceptionsFuture。然后组合(jobConfigFuture,(jobExceptionsResult,jobConfigResult)->{
返回新的JobDetails(jobDetailResult、jobExceptionsResult、jobConfigResult);
});
});
}).collect(Collectors.toList());
});
返回null;
我的问题是,当JobInfo为“new JobInfo(jobsResult,jobDetails)”时,如何在此处创建CompletableFuture

正如我所说,我对这一点还不熟悉,也许我的方法不好,有更好的解决方案吗

任何想法都很感激,谢谢

第一个工作版本:

private CompletableFuture<JobInfo> aggregateJobInfo() {

    final CompletableFuture<JobsResult> jobsResultFuture = restClient().getJobs();
    final CompletableFuture<List<String>> jobIdsFuture = jobsResultFuture.thenApply(JobInfoCollector::extractJobIds);

    final CompletableFuture<List<CompletableFuture<JobDetails>>> jobDetailsFutureListFuture =
            jobIdsFuture.thenApply(jobIds -> jobIds.stream().map(jobId -> {
                final CompletableFuture<JobDetailResult> jobDetailsResultFuture = restClient().getJobDetails(jobId);
                final CompletableFuture<JobExceptionsResult> jobExceptionsFuture = restClient().getJobExceptions(jobId);
                final CompletableFuture<JobConfigResult> jobConfigFuture = restClient().getJobConfig(jobId);
                return jobDetailsResultFuture.thenCompose(jobDetailResult ->
                        jobExceptionsFuture.thenCombine(jobConfigFuture, (jobExceptionsResult, jobConfigResult) ->
                                new JobDetails(jobDetailResult, jobExceptionsResult, jobConfigResult)));
            }).collect(Collectors.toList()));

    return jobDetailsFutureListFuture.thenCompose(jobDetailsFutures ->
            CompletableFuture.allOf(jobDetailsFutures.toArray(
                    new CompletableFuture[jobDetailsFutures.size()])).thenApply(aVoid ->
                    jobDetailsFutures.stream()
                            .map(CompletableFuture::join)
                            .collect(Collectors.toList())))
            .thenApply(jobDetails -> jobsResultFuture.thenApply(jobsResult ->
                    new JobInfo(jobsResult, jobDetails)))
            .join();
}
private CompletableFuture aggregateJobInfo(){
最终CompletableFuture作业ResultFuture=restClient().getJobs();
final CompletableFuture-jobIdsFuture=jobsResultFuture.thenApply(JobInfoCollector::extractJobIds);
最终完成的未来工作详细信息未来列表未来=
然后应用(jobIds->jobIds.stream().map(jobId->{
最终CompletableFuture jobDetailsResultFuture=restClient().getJobDetails(jobId);
最终CompletableFuture jobExceptionsFuture=restClient().getJobExceptions(jobId);
最终CompletableFuture jobConfigFuture=restClient().getJobConfig(jobId);
返回jobDetailsResultFuture.thenCompose(JobDetailsResult->
jobExceptionsFuture.thenCombine(jobConfigFuture,(jobExceptionsResult,jobConfigResult)->
新的JobDetails(jobDetailResult、jobExceptionsResult、jobConfigResult));
}).collect(Collectors.toList());
返回jobDetailsFutureListFuture。然后组合(jobDetailsFutures->
CompletableFuture.allOf(jobDetailsFutures.toArray(
新建CompletableFuture[jobDetailsFutures.size()])。然后应用(避免->
jobDetailsFutures.stream()
.map(CompletableFuture::join)
.collect(收集器.toList()))
.然后应用(作业详细信息->作业结果未来)。然后应用(作业结果->
新作业信息(作业结果、作业详细信息)))
.join();
}
您有:

  • CompletableFuture作业结果future
  • completable未来工作详细信息未来
  • JobInfo(作业结果a,列表b)
你想要

CompletableFuture

附加观察:
jobstreatsfourture
只有在
jobsResultFuture
完成时才能完成

因此,您可以实现以下功能:

  • List
    ->
    Void
    通过
    allOf
    中创建
  • 无效
    +
    列表
    (捕获变量)->
    列表
    通过
    然后应用
  • List
    +
    CompletableFuture
    (捕获变量)->
    JobInfo
    通过
    然后应用
  • 您只需在这些映射器函数中通过
    get()
    打开未来,因为由于其祖先未来在该点的依赖关系,未来保证在该点完成


    使用
    然后结合
    和流缩减的其他方法是可能的,但更详细,创建更多的中间未来。

    您粘贴的大多数代码似乎与问题不相关。您能否将其缩减到您需要的最小示例?问题是如何“映射”上面的未来数据是如此完整的未来被返回。抱歉,我不明白它。'waitAll'和Void是什么意思?意思是。它返回一个
    CompletableFuture
    ,因此获取数据的下一步将无法理解。尝试了jobDetailsListFuture。然后编写(jobDetailsFutures->{返回CompletableFuture.allOf(jobDetailsFutures.toArray(新的CompletableFuture[jobDetailsFutures.size()])。然后应用(避免->{???