首页 > 解决方案 > 在 Java 中进行多个异步调用时如何忽略失败的 CompletableFuture 调用?

问题描述

我想在 Java 中使用三个 REST 服务并行调用,我的代码如下:

private CompletableFuture < EmployeesListResponse > makeAsyncCall(Request request) {
 return CompletableFuture.supplyAsync(
  () -> {
   try {
    LOGGER.warn("- - - - - Employees Service async call - - - - -");
    return serviceObj.findServiceImpl(request);
   } catch (Exception e) {
    LOGGER.warn("service async call failed...", e);
   }
   return null;
  }, asyncExecutor).handle((res, ex) -> {
  LOGGER.warn("Exceptionally...", ex.toString(), res.toString());
  return new EmployeesListResponse();
 });
}

CompletableFuture < EmployeesListResponse > asyncFirstCall = makeAsyncCall(request);
CompletableFuture < EmployeesListResponse > asyncSecondCall = makeAsyncCall(request);
CompletableFuture < EmployeesListResponse > asyncThirdCall = makeAsyncCall(request);

CompletableFuture.allOf(asyncFirstCall, asyncSecondCall, asyncThirdCall).join();

在上面的代码中,我打了三个电话并使用CompletableFuture.allOf().join(). 当所有三个调用的服务响应均为 200 OK 时,此代码运行良好。

如果一个调用失败(500 Internal Server Error or 404 Not Found)而另外两个服务调用是 200 OK,那么代码抛出异常并且整个 API 响应因异常而失败。在这种情况下,我想忽略一个有异常的服务调用,并从其他两个调用返回成功响应。

在这种情况下如何处理忽略异常?

标签: javaspringmultithreadingasynchronousexception

解决方案


所以你试图在完成之前等待所有 3 个期货都完成,但是allOf当一个期货失败时,未来会立即返回。相反,您可以显式等待每个:

List<CompletableFuture<String>> allFutures = Arrays.asList(asyncFirstCall, asyncSecondCall,
        asyncThirdCall);
// await completion of all futures
allFutures.forEach(future -> {
    try {
        future.join();
    } catch (CompletionException ex) {
        // handled below.
    }
});

if (allFutures.stream().filter(CompletableFuture::isCompletedExceptionally).count() > 2) {
    throw new RuntimeException("Multiple failures");
}

// else continue with your business logic...

推荐阅读