繁体   English   中英

在 Java 8 中使用 CompletableFuture 进行异步 api 调用

[英]Asynchronous api call using CompletableFuture in Java 8

以下是我尝试使用 CompletableFuture 类实现的用例

  1. 我有一个 id 列表,我想为每个 id 进行 api 调用
  2. 我想从 api 调用中获取响应并将其保存在列表或地图中以供进一步处理
  3. 我也不想等到我得到所有 api 调用的响应。 我想设置一个时间限制并获取在那之前可用的任何数据。

我尝试了以下代码,但无法正常工作

// list content
List<Integer> ids = Arrays.asList(1,2,3,4,5);


// Api call using parallel stream - not sure how I can include a time limit here so that
// I can get partial list of updatedIds based on delay settings
List<Integer> updatedIds  = ids.parallelStream().map(item -> {
            // api call equivalent of increment 1
            return item+1;
        }).collect(Collectors.toList());



// Asynchronous api call using CompletableFuture class - not sure how I can
// dynamically call the function for all items in the ids list.
// Following is what I tried to do by reading 
// https://www.baeldung.com/java-completablefuture
encounterIdSet.parallelStream().forEach(id -> {
     CompletableFuture<Integer> completableFuture = CompletableFuture.supplyAsync(() -> serviceCall(id));
});
List<Integer> = completableFuture.get(60, TimeUnit.SECONDS); // may be in incorrect location 



// I want to process the list of returned integers here - whatever I am getting in 60 seconds timeout mentioned in timeout settings



// service call definition 
Integer serviceCall(id){
  return id +1;
}

你能指导我这个用例吗? 我需要 1. 超时设置 2. 异步数据处理 3. 未知数量的项目。

我正在使用 Java 8。

谢谢。

我可以想到两种方法,但有一些细微差别:

    List<CompletableFuture<Integer>> futures = ids.stream()
            .map(id -> CompletableFuture.supplyAsync(() -> id + 1))
            .collect(Collectors.toList());
    try {
        CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).get(60, TimeUnit.SECONDS);
    } catch (InterruptedException | ExecutionException | TimeoutException e) {
        // log
    }
    List<Integer> result = futures
            .stream()
            .filter(future -> future.isDone() && !future.isCompletedExceptionally())
            .map(CompletableFuture::join)
            .collect(Collectors.toList());   

或者

     List<Integer> result = ids.stream()
            .map(id -> CompletableFuture.supplyAsync(() -> id + 1))
            .map(cf -> {
                    try {
                        return cf.get(60, TimeUnit.SECONDS);
                    } catch (InterruptedException | ExecutionException | TimeoutException e) {
                        // log
                    }
                    return null;
            })
            .filter(Objects::nonNull)
            .collect(Collectors.toList());

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM