是否有可能基于某个条件使一个完整的未来失败?换句话说,将一个成功的结果转化为一个例外的结果?有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 一个未检查的异常也不是一个选项,因为它将改变消费者看到的异常的直接类型。
1条答案
按热度按时间dtcbnfnu1#
我已经再次阅读了你的问题(很抱歉之前的困惑),你所做的是完全正确的。事实上,我不知道有什么更好更惯用的方法来做这件事。虽然你在这里不需要它,
thenCompose
除了能够“压扁”一个CompletableFuture
,是非阻塞的。打电话时会出现一些情况thenCompose
而不是get/join
然后再包回一个CompletableFuture
,这很重要。这种用法存在于jdk的http客户机中,尽管您在这里没有利用它(这对您的示例来说也不重要),但在我看来,这是一个非常好的习惯。至于临时对象,我已经表达了我的观点,例如,与整个操作本身相比,性能下降几乎是不存在的。想想看
HashSet
使用HashMap
现在已经有20多年的历史了,人们没有抱怨。这些临时“持有者”对象从来都不是问题(在我目前的实践中)