我想拿出来与的综合影响CompletableFuturewhenComplete和thenCompose,具体如下:
CompletionStage而不仅仅是结果,类似于thenCompose。whenComplete,并且不会阻止异常传播。这篇文章接近我想要实现的目标,但我不想使用handle它隐藏异常。感谢您的任何想法。
我不相信CompletionStage或CompletableFuture为此提供任何单一的方法。但是,如果我正确理解您的要求,结合handlewiththenCompose应该可以满足您的需求。
handle无论父阶段是正常完成还是异常完成,都会执行一个阶段,并分别让您访问结果或错误。从这个阶段,你可以返回另一个CompletionStage可以正常完成或异常完成的,这取决于handle阶段收到的参数。
handle((T result, Throwable error) -> {
if (error != null) {
return CompletableFuture.<T>failedStage(error);
} else {
return processResult(result); // returns CompletionStage<T>
}
});
Run Code Online (Sandbox Code Playgroud)
现在你有一个CompletionStage<CompletionStage<T>>. 现在我们通过调用来执行平面地图操作thenCompose:
thenCompose(Function.identity());
Run Code Online (Sandbox Code Playgroud)
这给了我们一个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!");
}
}
Run Code Online (Sandbox Code Playgroud)
这将导致调用每个阶段并输出Hello, World!. 但是,如果您切换methodThatReturnsCompletionStage()到返回失败的阶段,thenApply则会跳过(因为未来已失败)并给出异常whenComplete(例如handle,为正常或异常完成调用)。
注意:上面的所有内容都CompletionStage直接使用界面,但使用CompletableFuture也同样有效(并且可能更可取)。