gpt4 book ai didi

java-8 - 组合多个 CompletableFuture

转载 作者:行者123 更新时间:2023-12-02 02:25:14 25 4
gpt4 key购买 nike

我有以下组件:

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;
}

它只是调用一些端点并聚合一些数据。现在我试图通过使用 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;

我的问题是当 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();
}

最佳答案

你有:

  • CompletableFuture<JobsResult> jobsResultFuture
  • CompletableFuture<List<CompletableFuture<JobDetails>>> jobDetailsFuture
  • JobInfo(JobsResult a, List<JobDetails> b)

你想要

CompletableFuture<JobInfo>

额外观察:jobDetailsFuture仅当 jobsResultFuture 时才能完成已完成。

因此您可以实现以下内容:

  1. List<CompletableFuture<JobDetails>> -> Void通过 allOfthenCompose
  2. Void + List<CompletableFuture<JobDetails>> (作为捕获的变量)-> List<JobDetails>通过 thenApply
  3. List<JobDetails> + CompletableFuture<JobsResult> (作为捕获的变量)-> JobInfo通过 thenApply

您可以通过get()简单地打开 future 。在这些映射器函数内部,因为由于当时其祖先 future 的依赖关系,future 保证在该点完成。

使用 thenCombine 的其他方法流减少是可能的,但更冗长并创造更多的中间 future 。

关于java-8 - 组合多个 CompletableFuture,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38036972/

25 4 0