如何解决CompletableFuture.allOf() :如何使用 .isCompletedExceptionally() 过滤结果?
在我的公司实施 CompletableFuture.allOf() 给我带来了同样的具体疑问,看看是否 我正在采取以下最佳方法:
(我创建了一个简单的演示项目只是为了说明简化问题) 在以下代码中:
public List<String> getResponse() {
List<CompletableFuture<String>> futureResultList = new ArrayList<>();
//Creating some randoms CompletableFuture
futureResultList.add(getFakeCompletableSuccess("Future 1"));
futureResultList.add(getFakeCompletableWithException("Future 2"));
futureResultList.add(getFakeCompletableWithException("Future 3"));
CompletableFuture[] futureResultArray =futureResultList.toArray(new
CompletableFuture[futureResultList.size()]);
try{
CompletableFuture.allOf(futureResultArray).join();
}catch(Exception e){
e.printstacktrace();
}
List<String> finalResult=processResults(futureResultList);
return finalResult;
}
public static CompletableFuture<String> getFakeCompletableSuccess(String value) {
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
try {
Thread.sleep(3000);
return value;
} catch (Exception e) {
throw new IllegalStateException(e);
}
});
return future;
}
public static CompletableFuture<String> getFakeCompletableWithException(String value) {
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
try {
Thread.sleep(3);
int error=1/0;
return value;
} catch (Exception e) {
throw new IllegalStateException(e);
}
});
return future;
}
public static List<String > processResults(List<CompletableFuture<String>> results){
return results.stream().filter(Objects::nonNull).filter(element -> !element.isCompletedExceptionally()).map((future) -> {
return future.join();
}).filter(Objects::nonNull).collect(Collectors.toList());
}
getResponse() :它将从某个“服务”调用,它的工作是执行一些异步操作 任务。等待任务完成后(join()),然后它会处理 结果。
getFakeCompletableSuccess() :检索一些成功的 CompletableFuture。
getFakeCompletableWithException() : 使用异常检索 CompletableFuture
processResults() : 基于 CompletableFuture 的 List ,它将提取每个的真实数据 那些期货。首先,它将过滤空值和 CompletableFutures 异常 (!element.isCompletedExceptionally())
如果我运行这个,一切都会好的! 但也有我不喜欢的细节。
如果我调试代码,当我在 processResult 方法中时,我可以看到要处理的 CompletableFuture 列表,它有 2 个 CompletableFuture with Exception,将在里面过滤。 这是一张图片:
但是在这一行:
try{
CompletableFuture.allOf(futureResultArray).join();
}catch(Exception e){
e.printstacktrace();
}
我有一个 Try and Catch(特别是捕获),它什么也不做,对我来说它看起来像是代码的味道。 但事实是,如果我删除它,应用程序就会崩溃,因为当然没有人捕捉到 getFakeCompletableWithException() 抛出的异常。
反正我做了修改,在创建CompletableFuture的时候加了下面一行:
futureResultList.add(getFakeCompletableSuccess("Future 1").exceptionally(e -> {
return null;
})););
futureResultList.add(getFakeCompletableWithException("Future 2").exceptionally(e -> {
return null;
})););
futureResultList.add(getFakeCompletableWithException("Future 3").exceptionally(e -> {
return null;
})););
好吧,现在我可以删除 try 和 catch,但是有两件事:
- 返回 null 可以吗?我在很多地方看到过
- 现在,当我调试并在 processResults 方法中再次停止时,我再也看不到 3 个 CompletableFutures 和 2 个异常。相反,我看到所有 CompletableFuture 都已完成,所有结果都在其中,不同之处在于其中 1 个结果为空。 所以 element.isCompletedExceptionally() 不再有用了。
如何实现与以前相同的功能?我的意思是在 processResult 内部,我可以通过 CompletableFuture 和 Exception 进行过滤,并且中间没有那个无意义的 try catch 。 我想要这样,因为 CompletableFuture with Exception 似乎更清楚过滤器,而不是在没有任何意义的情况下返回 null,只是为了让事情工作。
这是一个很长的帖子!希望你能帮助我!谢谢!
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。