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,将在里面过滤。 这是一张图片

When debugging inside processResult()

但是在这一行:

 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,但是有两件事:

  1. 返回 null 可以吗?我在很多地方看到过
  2. 现在,当我调试并在 processResults 方法中再次停止时,我再也看不到 3 个 CompletableFutures 和 2 个异常。相反,我看到所有 CompletableFuture 都已完成,所有结果都在其中,不同之处在于其中 1 个结果为空。 所以 element.isCompletedExceptionally() 不再有用了。

如何实现与以前相同的功能?我的意思是在 processResult 内部,我可以通过 CompletableFuture 和 Exception 进行过滤,并且中间没有那个无意义的 try catch 。 我想要这样,因为 CompletableFuture with Exception 似乎更清楚过滤器,而不是在没有任何意义的情况下返回 null,只是为了让事情工作。

这是一个很长的帖子!希望你能帮助我!谢谢!

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)