CompletableFuture 中异常处理的 finally 块等价物
finally block equivalent for exception handling in CompletableFuture
我有 CompletableFuture
可以 return 结果或异常。我想在异常和正常结果的情况下执行 运行 一些通用代码。类似于try catch finally
块
当前实施
CompletableFuture<Integer> future= CompletableFuture.supplyAsync(this::findAccountNumber)
.thenApply(this::calculateBalance)
.thenApply(this::notifyBalance)
.exceptionally(ex -> {
//My Exception Handling logic
return 0;
});
我可以把我的最终逻辑放在哪里?
handle()
方法提供更灵活的方法。它需要一个函数接收正确的结果或异常:
来自 java 文档
handle(BiFunction<? super T,Throwable,? extends U> fn)
Returns a new CompletionStage that, when this stage completes either
normally or exceptionally, is executed with this stage's result and
exception as arguments to the supplied function.
CompletableFuture<Integer> thenApply = CompletableFuture.supplyAsync(this::findAccountNumber)
.thenApply(this::calculateBalance)
.thenApply(this::notifyBalance)
.handle((ok, ex) -> {
System.out.println("Code That we want to run in finally ");
if (ok != null) {
System.out.println("No Exception !!");
} else {
System.out.println("Got Exception " + ex.getMessage());
return -1;
}
return ok;
});
最接近 finally
的是 whenComplete
。像 handle
一样,它接受一个接收结果值或 throwable 的函数,但它不提供替换结果值,而是新的完成阶段不会改变结果,就像 finally
.
所以
static int decode(String s) {
try {
return Integer.parseInt(s);
}
finally {
System.out.println("finally action");
}
}
相当于
static int decode1(String s) {
return CompletableFuture.completedFuture(s)
.thenApply(Integer::parseInt)
.whenComplete((myParsedInt, error) -> System.out.println("finally action"))
.join();
}
所以当使用 with
for(String s: Arrays.asList("1234", "foo bar")) try {
System.out.println("decoded: "+decode(s));
} catch(Exception ex) {
System.out.println("decoding "+s+" failed with "+ex);
}
第一个变体打印
finally action
decoded: 1234
finally action
decoding foo bar failed with java.lang.NumberFormatException: For input string: "foo bar"
而后者打印
finally action
decoded: 1234
finally action
decoding foo bar failed with java.util.concurrent.CompletionException: java.lang.NumberFormatException: For input string: "foo bar"
两者的共同点是,如果 try 块/前一阶段异常完成,finally 操作中抛出的异常将取代原始结果,隐藏异常。
我有 CompletableFuture
可以 return 结果或异常。我想在异常和正常结果的情况下执行 运行 一些通用代码。类似于try catch finally
块
当前实施
CompletableFuture<Integer> future= CompletableFuture.supplyAsync(this::findAccountNumber)
.thenApply(this::calculateBalance)
.thenApply(this::notifyBalance)
.exceptionally(ex -> {
//My Exception Handling logic
return 0;
});
我可以把我的最终逻辑放在哪里?
handle()
方法提供更灵活的方法。它需要一个函数接收正确的结果或异常:
来自 java 文档
handle(BiFunction<? super T,Throwable,? extends U> fn)
Returns a new CompletionStage that, when this stage completes either normally or exceptionally, is executed with this stage's result and exception as arguments to the supplied function.
CompletableFuture<Integer> thenApply = CompletableFuture.supplyAsync(this::findAccountNumber)
.thenApply(this::calculateBalance)
.thenApply(this::notifyBalance)
.handle((ok, ex) -> {
System.out.println("Code That we want to run in finally ");
if (ok != null) {
System.out.println("No Exception !!");
} else {
System.out.println("Got Exception " + ex.getMessage());
return -1;
}
return ok;
});
最接近 finally
的是 whenComplete
。像 handle
一样,它接受一个接收结果值或 throwable 的函数,但它不提供替换结果值,而是新的完成阶段不会改变结果,就像 finally
.
所以
static int decode(String s) {
try {
return Integer.parseInt(s);
}
finally {
System.out.println("finally action");
}
}
相当于
static int decode1(String s) {
return CompletableFuture.completedFuture(s)
.thenApply(Integer::parseInt)
.whenComplete((myParsedInt, error) -> System.out.println("finally action"))
.join();
}
所以当使用 with
for(String s: Arrays.asList("1234", "foo bar")) try {
System.out.println("decoded: "+decode(s));
} catch(Exception ex) {
System.out.println("decoding "+s+" failed with "+ex);
}
第一个变体打印
finally action
decoded: 1234
finally action
decoding foo bar failed with java.lang.NumberFormatException: For input string: "foo bar"
而后者打印
finally action
decoded: 1234
finally action
decoding foo bar failed with java.util.concurrent.CompletionException: java.lang.NumberFormatException: For input string: "foo bar"
两者的共同点是,如果 try 块/前一阶段异常完成,finally 操作中抛出的异常将取代原始结果,隐藏异常。