如何控制 CompletableFuture 的流程?
How to control the flow of a CompletableFuture?
考虑以下代码:
final CompletableFuture<Object> future = giveMeFuture();
future.thenAcceptAsync(o -> {
throw new RuntimeException("Some random exception happened.");
}).exceptionally(throwable -> {
System.out.println("EXCEPTION 1: " + throwable.getLocalizedMessage());
return null;
});
future.exceptionally(throwable -> {
System.out.println("EXCEPTION 2: " + throwable.getLocalizedMessage());
return null;
});
我注意到以下行为:
future正常完成时,只打印EXCEPTION 1
。这符合预期,因为我们在 thenAcceptAsync
.
中抛出异常
future异常完成时,EXCEPTION 1
和EXCEPTION 2
都打印出来
我只想在执行thenAcceptAsync
时出现异常时打印EXCEPTION 1
。所以第二种情况,future异常完成的时候,我只想打印EXCEPTION 2
如何使用 CompletableFuture
执行此操作?我知道我可以在 thenAcceptAsync
中添加一个很好的旧 try / catch
,但我想知道这是否可以仅使用 CompletableFuture
功能来完成。
更新
以下流程将不起作用:
future
.exceptionally(throwable -> {
System.out.println("EXCEPTION 2: " +throwable.getLocalizedMessage());
return null;
})
.thenAcceptAsync(o -> {
throw new RuntimeException("Some random exception happened.");
})
.exceptionally(throwable -> {
System.out.println("EXCEPTION 1: " + throwable.getLocalizedMessage());
return null;
});
如果我们进入 EXCEPTION 2
流程,我们 return null
。现在使用 null
参数调用 thenAcceptAsync
。我们可以在参数 o
上添加 null
检查,但我认为这不是一个好主意。我们在唤醒执行线程发现参数o
是null
:
.thenAcceptAsync(o -> {
if (o != null) {
// do something with the parameter
throw new RuntimeException("Some random exception happened.");
}
})
怎么样:
future
.handleAsync((object, throwable) -> {
if (throwable !=null) {
System.out.println("EXCEPTION from future completion: " + throwable.getClass().getName());
return null;
}
else {
throw new IllegalStateException("async processing failed");
}
})
.exceptionally(throwable -> {
System.out.println("EXCEPTION from completion stage: " + throwable.getClass().getName());
return null;
});
或将您的代码更改为:
future
.exceptionally(throwable -> {
System.out.println("EXCEPTION 2: " +throwable.getLocalizedMessage());
return null;
})
.thenAcceptAsync(o -> {
throw new RuntimeException("Some random exception happened.");
})
.exceptionally(throwable -> {
System.out.println("EXCEPTION 1: " + throwable.getLocalizedMessage());
return null;
});
每次将操作链接到 future 时,它都会与其他操作分开执行 "chaining"。您正在制作两个操作链,一个使用 future.thenAcceptAsync
,另一个使用 future.exceptionally
,并且它们彼此分开执行。
考虑以下代码:
final CompletableFuture<Object> future = giveMeFuture();
future.thenAcceptAsync(o -> {
throw new RuntimeException("Some random exception happened.");
}).exceptionally(throwable -> {
System.out.println("EXCEPTION 1: " + throwable.getLocalizedMessage());
return null;
});
future.exceptionally(throwable -> {
System.out.println("EXCEPTION 2: " + throwable.getLocalizedMessage());
return null;
});
我注意到以下行为:
future正常完成时,只打印
EXCEPTION 1
。这符合预期,因为我们在thenAcceptAsync
. 中抛出异常
future异常完成时,
EXCEPTION 1
和EXCEPTION 2
都打印出来
我只想在执行thenAcceptAsync
时出现异常时打印EXCEPTION 1
。所以第二种情况,future异常完成的时候,我只想打印EXCEPTION 2
如何使用 CompletableFuture
执行此操作?我知道我可以在 thenAcceptAsync
中添加一个很好的旧 try / catch
,但我想知道这是否可以仅使用 CompletableFuture
功能来完成。
更新
以下流程将不起作用:
future
.exceptionally(throwable -> {
System.out.println("EXCEPTION 2: " +throwable.getLocalizedMessage());
return null;
})
.thenAcceptAsync(o -> {
throw new RuntimeException("Some random exception happened.");
})
.exceptionally(throwable -> {
System.out.println("EXCEPTION 1: " + throwable.getLocalizedMessage());
return null;
});
如果我们进入 EXCEPTION 2
流程,我们 return null
。现在使用 null
参数调用 thenAcceptAsync
。我们可以在参数 o
上添加 null
检查,但我认为这不是一个好主意。我们在唤醒执行线程发现参数o
是null
:
.thenAcceptAsync(o -> {
if (o != null) {
// do something with the parameter
throw new RuntimeException("Some random exception happened.");
}
})
怎么样:
future
.handleAsync((object, throwable) -> {
if (throwable !=null) {
System.out.println("EXCEPTION from future completion: " + throwable.getClass().getName());
return null;
}
else {
throw new IllegalStateException("async processing failed");
}
})
.exceptionally(throwable -> {
System.out.println("EXCEPTION from completion stage: " + throwable.getClass().getName());
return null;
});
或将您的代码更改为:
future
.exceptionally(throwable -> {
System.out.println("EXCEPTION 2: " +throwable.getLocalizedMessage());
return null;
})
.thenAcceptAsync(o -> {
throw new RuntimeException("Some random exception happened.");
})
.exceptionally(throwable -> {
System.out.println("EXCEPTION 1: " + throwable.getLocalizedMessage());
return null;
});
每次将操作链接到 future 时,它都会与其他操作分开执行 "chaining"。您正在制作两个操作链,一个使用 future.thenAcceptAsync
,另一个使用 future.exceptionally
,并且它们彼此分开执行。