微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

基于条件的失败 CompletableFuture

如何解决基于条件的失败 CompletableFuture

是否有可能根据条件使 CompletableFuture 失败?换句话说,将成功的结果转换为异常的结果?有它的 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 表达这一点?每个解决方案在性能方面的比较如何(或者差异几乎可以忽略不计?)

附注。我事先不知道要传播的异常类型,但让我们假设它是一个已检查的异常,并且不能更改为未检查的异常。包装在未经检查的异常中也不是一种选择,因为它会改变消费者看到的异常的直接类型。

解决方法

我再次阅读了您的问题(抱歉之前的混淆),您所做的完全正确。事实上,我不知道更好、更惯用的方法来做到这一点。虽然在这里您不需要它,但 thenCompose 除了能够“展平”CompletableFuture 之外,是非阻塞的。在某些情况下,调用 thenCompose 而不是 get/join 然后包装回 CompletableFuture,这很重要。这种用法存在于 jdk 的 http 客户端中,尽管您在这里没有利用它(对于您的示例也没有真正的影响),但这是一个很好的成长习惯,imo。

对于临时对象,我已经表达了我的观点,与整个操作本身相比,性能下降几乎不存在,例如 here。还想一想 HashSet 在引擎盖下使用 HashMap 已经 20 多年了,而且人们没有抱怨。这些临时的“持有者”对象从来都不是问题(在我目前的实践中)

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。