繁体   English   中英

在 Java 中进行多个 Async 调用时,如何忽略失败的 CompletableFuture 调用?

[英]How to ignore a failed CompletableFuture call when multiple Async calls are made in Java?

我想在 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 响应因异常而失败。 在这种情况下,我想忽略一个有异常的服务调用,并从其他两个调用返回成功响应。

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

所以你试图在完成之前等待所有 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...

您不需要在 try catch 块中处理异常,因为您已经在处理handle()方法。 不管你是否得到异常,但这个 handle() 方法每次都会执行。 您只需要检查是否有任何异常,如果是,则根据需要发送默认响应。

private CompletableFuture < EmployeesListResponse > makeAsyncCall(Request request) {
     return CompletableFuture.supplyAsync(
      () -> {
        LOGGER.warn("- - - - - Employees Service async call - - - - -");
        return serviceObj.findServiceImpl(request);
      }, asyncExecutor).handle((res, ex) -> {
          if (ex != null) {
              LOGGER.warn("Exceptionally...", ex);
              return "what ever default you want to return";
   //         or return new EmployeesListResponse();
            }
            return res;
     });
    }

如果您想忽略,请尝试如下

CompletableFuture<Void> allOf = CompletableFuture.allOf(asyncFirstCall,asyncSecondCall);
allOf.whenComplete((aVoid, throwable) -> {
    allOf.join();
});

暂无
暂无

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

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