CompletableFuture handle 和 completeExceptionally 不能一起工作?
CompletableFuture handle and completeExceptionally cannot work together?
我试图在 CompletableFuture
中发生异常时设置一个 默认值 我通过 handle
方法使其工作如下:
private static void testHandle() {
String name = null;
CompletableFuture<String> completableFuture
= CompletableFuture.supplyAsync(() -> {
if (name == null) {
throw new RuntimeException("Computation error!");
}
return "Hello, " + name;
}).handle((s, t) -> s != null ? s : "Hello, Stranger!" + t.toString());
out.println(completableFuture.join());
}
但是当我试图在坏事发生时使用 completeExceptionally
停止 CompletableFuture
并如下跟踪 异常 我无法捕获 异常 就像我刚才做的那样。
private static void testCompleteExceptionally() {
String name = "Hearen";
CompletableFuture<String> completableFuture
= CompletableFuture.supplyAsync(() -> {
delay(500L);
if (name == null) {
throw new RuntimeException("Computation error!");
}
return "Hello, " + name;
}).handle((s, t) -> {
try {
throw t.getCause();
} catch (Throwable e) {
out.println(e.toString()); // I was hoping to record the custom exceptions here;
}
return s != null ? s : "Hello, Stranger!" + t.toString();
});
if (name != null) {
completableFuture.completeExceptionally(new RuntimeException("Calculation failed!")); // when bad things happen, I try to complete it by exception;
}
out.println(completableFuture.join());
}
已更新 2018-06-09 感谢您的帮助,@Daniele
private static void testCompleteExceptionally() {
String name = "Hearen";
CompletableFuture<String> completableFuture
= CompletableFuture.supplyAsync(() -> {
delay(500L);
if (name == null) {
throw new RuntimeException("Computation error!");
}
return "Hello, " + name;
});
if (name != null) {
completableFuture.completeExceptionally(new RuntimeException("Calculation failed!"));
}
out.println(completableFuture.handle((s, t) -> s != null ? s : "Hello, Stranger!" + t.toString()).join());
}
join()
之前包含的 句柄 按预期工作。但在这种情况下,returned value
将是 null
。
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.
您正在构建一个 future
,管道与 handle
(因此获得另一个未来),然后异常完成由 handle
返回的未来。
您应该特别完成内部 future
本身,而不是 handle
。
这里的重点是handle
returns另一个未来;并且您不应该例外地完成 "outer" 未来,因为这样做会绕过处理行为。
代码下方;
package stackOv;
import java.util.concurrent.CompletableFuture;
import java.util.function.BiFunction;
import java.util.function.Supplier;
public class TestHandle {
BiFunction<String, Throwable, String> handle2 = new BiFunction<String, Throwable, String>() {
@Override
public String apply(String s, Throwable t) {
try {
throw t.getCause();
} catch (Throwable e) {
// I was hoping to record the custom exceptions here;
System.out.println(e.toString());
}
return s != null ? s : "Hello, Stranger!" + t.toString();
}
};
private void testCompleteExceptionally() {
String name = "Hearen";
Supplier<String> supplier2 = () -> {
delay(500L);
if (name == null) {
throw new RuntimeException("Computation error!");
}
return "Hello, " + name;
};
CompletableFuture<String> completableFuture = CompletableFuture.supplyAsync(supplier2);
if (name != null) {
// when bad things happen, I try to complete it by exception;
completableFuture.completeExceptionally(new RuntimeException("Calculation failed!"));
}
System.out.println(completableFuture.handle(handle2).join());
}
public static void main(String[] args) {
TestHandle th = new TestHandle();
th.testCompleteExceptionally();
}
private static void delay(long milli) {
try { Thread.sleep(milli); } catch (InterruptedException e) {}
}
}
我试图在 CompletableFuture
中发生异常时设置一个 默认值 我通过 handle
方法使其工作如下:
private static void testHandle() {
String name = null;
CompletableFuture<String> completableFuture
= CompletableFuture.supplyAsync(() -> {
if (name == null) {
throw new RuntimeException("Computation error!");
}
return "Hello, " + name;
}).handle((s, t) -> s != null ? s : "Hello, Stranger!" + t.toString());
out.println(completableFuture.join());
}
但是当我试图在坏事发生时使用 completeExceptionally
停止 CompletableFuture
并如下跟踪 异常 我无法捕获 异常 就像我刚才做的那样。
private static void testCompleteExceptionally() {
String name = "Hearen";
CompletableFuture<String> completableFuture
= CompletableFuture.supplyAsync(() -> {
delay(500L);
if (name == null) {
throw new RuntimeException("Computation error!");
}
return "Hello, " + name;
}).handle((s, t) -> {
try {
throw t.getCause();
} catch (Throwable e) {
out.println(e.toString()); // I was hoping to record the custom exceptions here;
}
return s != null ? s : "Hello, Stranger!" + t.toString();
});
if (name != null) {
completableFuture.completeExceptionally(new RuntimeException("Calculation failed!")); // when bad things happen, I try to complete it by exception;
}
out.println(completableFuture.join());
}
已更新 2018-06-09 感谢您的帮助,@Daniele
private static void testCompleteExceptionally() {
String name = "Hearen";
CompletableFuture<String> completableFuture
= CompletableFuture.supplyAsync(() -> {
delay(500L);
if (name == null) {
throw new RuntimeException("Computation error!");
}
return "Hello, " + name;
});
if (name != null) {
completableFuture.completeExceptionally(new RuntimeException("Calculation failed!"));
}
out.println(completableFuture.handle((s, t) -> s != null ? s : "Hello, Stranger!" + t.toString()).join());
}
join()
之前包含的 句柄 按预期工作。但在这种情况下,returned value
将是 null
。
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.
您正在构建一个 future
,管道与 handle
(因此获得另一个未来),然后异常完成由 handle
返回的未来。
您应该特别完成内部 future
本身,而不是 handle
。
这里的重点是handle
returns另一个未来;并且您不应该例外地完成 "outer" 未来,因为这样做会绕过处理行为。
代码下方;
package stackOv;
import java.util.concurrent.CompletableFuture;
import java.util.function.BiFunction;
import java.util.function.Supplier;
public class TestHandle {
BiFunction<String, Throwable, String> handle2 = new BiFunction<String, Throwable, String>() {
@Override
public String apply(String s, Throwable t) {
try {
throw t.getCause();
} catch (Throwable e) {
// I was hoping to record the custom exceptions here;
System.out.println(e.toString());
}
return s != null ? s : "Hello, Stranger!" + t.toString();
}
};
private void testCompleteExceptionally() {
String name = "Hearen";
Supplier<String> supplier2 = () -> {
delay(500L);
if (name == null) {
throw new RuntimeException("Computation error!");
}
return "Hello, " + name;
};
CompletableFuture<String> completableFuture = CompletableFuture.supplyAsync(supplier2);
if (name != null) {
// when bad things happen, I try to complete it by exception;
completableFuture.completeExceptionally(new RuntimeException("Calculation failed!"));
}
System.out.println(completableFuture.handle(handle2).join());
}
public static void main(String[] args) {
TestHandle th = new TestHandle();
th.testCompleteExceptionally();
}
private static void delay(long milli) {
try { Thread.sleep(milli); } catch (InterruptedException e) {}
}
}