基于条件的失败completablefuture

dfuffjeb  于 2021-08-25  发布在  Java
关注(0)|答案(1)|浏览(390)

是否有可能基于某个条件使一个完整的未来失败?换句话说,将一个成功的结果转化为一个例外的结果?有api吗?
目前,我正在做以下工作,但感觉很尴尬和复杂:

CompletableFuture<CustomClass> inputFuture = doWork();
CompletableFuture<CustomClass> outputFuture = new CompletableFuture<>();

inputFuture.whenComplete((result, ex) -> {
  if (ex != null) {
    outputFuture.completeExceptionally(ex);
  } else {
    Outcome outcome = verify(result);
    if (outcome.isNegativeResult()) {
      outputFuture.completeExceptionally(outcome.getException());
    } else {
      outputFuture.complete(result);
    }
  }
});

return outputFuture;

不是很有表现力。我知道有 thenCompose 自动处理异常情况,并将其减少到:

CompletableFuture<CustomClass> inputFuture = doWork();

return inputFuture.thenCompose(result -> {
  Outcome outcome = verify(result);
  if (outcome.isNegativeResult()) {
    return CompletableFuture.failedFuture(outcome.getException());
  } else {
    return CompletableFuture.completedFuture(result);
  }
});

这是我能想到的最好的方法,但仍然感觉有点笨拙(临时的一次性期货是新的,只是为了传递价值)。
使用completablefuture api是否有一种更简短、更惯用或更简洁的表达方式?在性能方面,每个解决方案的比较结果如何(或者差异是否可以忽略不计?)
另外,我不知道要预先传播的异常的类型,但是让我们假设它是一个已检查的异常,并且不能更改为未检查的异常。 Package 一个未检查的异常也不是一个选项,因为它将改变消费者看到的异常的直接类型。

dtcbnfnu

dtcbnfnu1#

我已经再次阅读了你的问题(很抱歉之前的困惑),你所做的是完全正确的。事实上,我不知道有什么更好更惯用的方法来做这件事。虽然你在这里不需要它, thenCompose 除了能够“压扁”一个 CompletableFuture ,是非阻塞的。打电话时会出现一些情况 thenCompose 而不是 get/join 然后再包回一个 CompletableFuture ,这很重要。这种用法存在于jdk的http客户机中,尽管您在这里没有利用它(这对您的示例来说也不重要),但在我看来,这是一个非常好的习惯。
至于临时对象,我已经表达了我的观点,例如,与整个操作本身相比,性能下降几乎是不存在的。想想看 HashSet 使用 HashMap 现在已经有20多年的历史了,人们没有抱怨。这些临时“持有者”对象从来都不是问题(在我目前的实践中)

相关问题