在Spring Boot微服务中完成异步处理响应后,有没有办法处理它们?

时间:2019-06-18 05:15:24

标签: java spring spring-boot asynchronous microservices

假设在一个函数中有5个不同的服务调用,并且它们都是异步的,我想在完成每个过程时对其进行处理。

例如,这些是3种不同类别的3种不同功能

@Async
public CompletableFuture<Actor> lookForId(String id) throws InterruptedException {
    LOG.info("Looking up Movie ID: {}", Id);
    String url = "http://localhost:7073/data/" + id;
    Actor results = restTemplate.getForObject(url, Actors.class);
    // Artificial delay of 1s for demonstration purposes
    Thread.sleep(1000L);
    return CompletableFuture.completedFuture(results);
}

@Async
public CompletableFuture<Singer> lookForId(String id) throws InterruptedException {
    LOG.info("Looking up Movie ID: {}", id);
    String url = "http://localhost:7075/data/" + id;
    Singer results = restTemplate.getForObject(url, Singer.class);
    // Artificial delay of 1s for demonstration purposes
    Thread.sleep(1000L);
    return CompletableFuture.completedFuture(results);
}

@Async
public CompletableFuture<Writer> lookForId(String id) throws InterruptedException {
    LOG.info("Looking up Movie ID: {}", id);
    String url = "http://localhost:7078/data/" + id;
    Writer results = restTemplate.getForObject(url, Writer.class);
    // Artificial delay of 1s for demonstration purposes
    Thread.sleep(1000L);
    return CompletableFuture.completedFuture(results);
}

调用它们的函数就像下面的代码

public String getResp() throws InterruptedException, ExecutionException {
    long start = System.currentTimeMillis();
    CompletableFuture<Actor> page1 = actorAsyncService.lookForId("0");
    CompletableFuture<Singer> page2 = singerAsyncService.lookForId("2");
    CompletableFuture<Writer> page3 = singerAsyncService.lookForId("4");
    String respStr = page1.get() + "||" + page2.get() + "||" + page3.get() ;
    System.out.println(">>>>>>>>>>>> Elapsed time: " + (System.currentTimeMillis() - start));
    System.out.println("respStr : " + respStr);
    return respStr;
}

此处,流程等待每个流程完成,然后发送回响应,但我希望以某种方式,一旦任何流程完成,服务应将响应返回给调用函数但当其余的过程完成或终止或给出错误响应时,也应该能够处理其他服务调用提供的响应。

例如如果page2进程完成,则该进程的响应返回给调用函数,但该进程完成后,该函数仍应能够处理来自page1和page2的响应。

1 个答案:

答案 0 :(得分:0)

CompletableFuture.anyOf()返回一个新的CompletableFuture,当给定的CompletableFuture中的任何一个完成时,新的CompletableFuture将完成,并具有相同的结果。

这是我的例子:

public static void main(String[] args) throws ExecutionException, InterruptedException {
        CompletableFuture<String> task1 = CompletableFuture.supplyAsync(() -> {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("task 1 finished");
            return "task 1";
        });

        CompletableFuture<String> task2 = CompletableFuture.supplyAsync(() -> {
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("task 2 finished");
            return "task 2";
        });

        CompletableFuture<String> task3 = CompletableFuture.supplyAsync(() -> {
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("task 3 finished");
            return "task 3";
        });
        CompletableFuture<Object> future = CompletableFuture.anyOf(task1, task2, task3);
        String result = (String)future.get();
        System.out.println(result);

        task1.join();
        task2.join();
        task3.join();
    }

输出为:

task 1 finished
task 1
task 2 finished
task 3 finished