有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java Completable future可命中多个rest服务并合并结果

我有一个问题:

我有一个rest enpoint,它给了我1000个结果。每页每次我都要增加页数 增加页数,重新拨打rest电话; pagenum值将为0,1,2,直到总页数。 通过传递pagenum,我使用一个可完成的future进行了一个异步调用

所以假设总页面是5,那么5个线程将得到结果 然后我必须得到结果,并将所有结果合并

为此,我使用--respon=resp。get(); 但我读到了它的封锁电话

所以我的问题是如何异步获得结果并将其组合。 在下面的代码中,我正在做未来。get()将停止以异步运行代码

请评论

for (int pagenum = 1; pagenum <=totalPage; pagenum++) {
            
        String respon=   CompletableFuture.supplyAsync(() -> {
                return new RestTemplate().exchange(getUsersByID(roleId, maxCount, 
                        pagenum), HttpMethod.GET,
                        entity, String.class).getBody();
            });             
                                try {
                                    respon = resp.get();
                                    
                                } catch (InterruptedException | ExecutionException e) {
                                    // TODO Auto-generated catch block
                                    e.printStackTrace();
                                }
                                
            }
           
         }

共 (1) 个答案

  1. # 1 楼答案

    其中一个选择可能是创造组合的未来:

        int MAX_PAGE_NUM = 100;
        List<CompletableFuture<String>> futures = new ArrayList<>();
        for(int pagenum = 1; pagenum < MAX_PAGE_NUM; pagenum++) {
            futures.add(  CompletableFuture.supplyAsync(() -> {
                return new RestTemplate().exchange(getUsersByID(roleId, maxCount,
                    pagenum), HttpMethod.GET,
                    entity, String.class).getBody();
            }), executor);
        }
    
        CompletableFuture combinedFuture = CompletableFuture.allOf(futures.toArray(new CompletableFuture[MAX_PAGE_NUM]));
        try {
            combinedFuture.get();
            
            for (CompletableFuture<String> future : futures) {
                String response = future.get();
                //process the response
            }
        } catch (InterruptedException | ExecutionException e) {
            e.printStackTrace();
        }
    

    上面的例子应该可以帮助您并行运行所有页面请求,并在处理完所有未来后处理结果

    如果希望同时处理每个结果,而不考虑其他结果,以便响应处理是异步的,那么可以使用thenApply()方法

        int MAX_PAGE_NUM = 100;
        List<CompletableFuture<String>> futures = new ArrayList<>();
        for(int pagenum = 1; pagenum < MAX_PAGE_NUM; pagenum++) {
            futures.add(  CompletableFuture.supplyAsync(() -> {
                return new RestTemplate().exchange(getUsersByID(roleId, maxCount,
                    pagenum), HttpMethod.GET,
                    entity, String.class).getBody();
            }).thenApply( (s) -> {
                //process the response concurrently
                return s;
            }), executor);
        }
    
        CompletableFuture combinedFuture = CompletableFuture.allOf(futures.toArray(new CompletableFuture[MAX_PAGE_NUM]));
    
        try {
            combinedFuture.get();
        } catch (InterruptedException | ExecutionException e) {
            e.printStackTrace();
        }
    

    我还建议对combinedFututre使用超时限制。得到()

    combinedFuture.get(50, TimeUnit.SECONDS);
    

    这篇文章应该能帮助你了解更多细节https://www.baeldung.com/java-completablefuture