[英]Java collecting results of CompletableFuture from multiple calls
[英]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.