java - 如何获得whenComplete和thenCompose的组合效果?
问题描述
我正在尝试提出具有 and 组合效果的 CompletableFuture whenComplete
,thenCompose
特别是:
- 返回 a
CompletionStage
而不仅仅是结果,类似于thenCompose
. - 即使在前一阶段异常完成时也会执行,类似于
whenComplete
,并且不会阻止异常传播。
这篇文章接近我想要实现的目标,但我不想使用handle
隐藏异常的方法。感谢您的任何想法。
解决方案
我不相信CompletionStage
或CompletableFuture
为此提供任何单一方法。但是,如果我正确理解您的要求,结合handle
应该thenCompose
做您想做的事。
handle
无论父阶段是正常完成还是异常完成,都会执行一个阶段,并分别让您访问结果或错误。从这个阶段开始,您可以返回另一个CompletionStage
,它可以正常完成,也可以异常完成,具体取决于handle
阶段接收到的参数。
handle((T result, Throwable error) -> {
if (error != null) {
return CompletableFuture.<T>failedStage(error);
} else {
return processResult(result); // returns CompletionStage<T>
}
});
现在你有一个CompletionStage<CompletionStage<T>>
. 现在我们通过调用执行平面地图操作thenCompose
:
thenCompose(Function.identity());
这给了我们一个CompletionStage<T>
. 这CompletionStage<T>
将是 . 返回的任何实例handle
。如果该实例是一个失败的阶段,那么异常仍然会传播;否则,结果将传递到依赖于该thenCompose
阶段的任何阶段,并且处理正常继续。
您可以通过以下示例看到这一点:
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionStage;
public class Main {
public static void main(String[] args) {
methodThatReturnsCompletionStage()
.handle((result, error) -> {
if (error != null) {
return CompletableFuture.<String>failedStage(error);
} else {
return processResult(result);
}
})
.thenCompose(future -> {
System.out.println("#thenCompose invoked");
return future; // Identity function
})
.thenApply(result -> {
System.out.println("#thenApply invoked");
return result; // Identity function (exists to show intermediary stage)
})
.whenComplete((result, error) -> {
System.out.println("#whenComplete invoked");
if (error != null) {
error.printStackTrace(System.out);
} else {
System.out.println(result);
};
});
}
private static CompletionStage<String> methodThatReturnsCompletionStage() {
return CompletableFuture.completedStage("Hello");
// return CompletableFuture.failedStage(new RuntimeException("OOPS"));
}
private static CompletionStage<String> processResult(String result) {
return CompletableFuture.completedFuture(result + ", World!");
}
}
这将导致每个阶段都被调用并输出Hello, World!
. 但是,如果您切换methodThatReturnsCompletionStage()
到返回失败的阶段,thenApply
则会跳过(因为未来已失败)并给出异常whenComplete
(如handle
,为正常或异常完成调用)。
注意:以上所有内容都CompletionStage
直接使用接口,但使用CompletableFuture
效果也一样好(并且可能更可取)。
推荐阅读
- asp.net - VB.Net - Adding WebApi 5 to Existing MVC 5 Site
- vue.js - 不调用 Vue 道具验证
- php - PHP - 尽管没有添加文件,但 ZipArchive 关闭返回 true
- php - SQL - 将日期时间与当前时间进行比较
- vhdl - Quartus 17.1 中使用的 Quartus 14.1 加密文件
- docker - 在 Oracle VM VirtualBox 上为 Docker 配置 corp 代理
- c# - EF Core FindAsync 仅返回根对象
- batch-file - How to reduce value of variable in batch?
- sql - MongoDB中的3个表连接
- java - Trouble generating random -1 through +1 in Java