Java8 CompletableFuture recoverWith等效物?例如,例外情况下,但返回完整的未来<;U>;
我看不到一种处理异步结果异常的明显方法。 例如,如果我想重试异步操作。我希望这样,但是handleAsync并没有做你认为它做的事情——它异步地在另一个线程上运行回调。在此处返回CompletionStage是不正确的。当今的危险问题:Java8 CompletableFuture recoverWith等效物?例如,例外情况下,但返回完整的未来<;U>;,java,java-8,completable-future,Java,Java 8,Completable Future,我看不到一种处理异步结果异常的明显方法。 例如,如果我想重试异步操作。我希望这样,但是handleAsync并没有做你认为它做的事情——它异步地在另一个线程上运行回调。在此处返回CompletionStage是不正确的。当今的危险问题:然后应用是对然后编写,就像例外是对什么 CompletionStage<String> cf = askPong("cause error").handleAsync((x, t) -> { if (t != null) {
然后应用
是对然后编写
,就像例外
是对什么
CompletionStage<String> cf = askPong("cause error").handleAsync((x, t) -> {
if (t != null) {
return askPong("Ping");
} else {
return x;
}
});
CompletionStage cf=askPong(“原因错误”)。handleAsync((x,t)->{
如果(t!=null){
返回askPong(“Ping”);
}否则{
返回x;
}
});
askPong问演员:
public CompletionStage<String> askPong(String message){
Future sFuture = ask(actorRef, message, 1000);
final CompletionStage<String> cs = toJava(sFuture);
return cs;
}
public CompletionStage askPong(字符串消息){
未来sFuture=ask(actorRef,message,1000);
最终完工阶段cs=toJava(sFuture);
返回cs;
}
这就是你要找的吗
askPong("cause error")
.handle( (pong, ex) -> ex == null
? CompletableFuture.completedFuture(pong)
: askPong("Ping")
).thenCompose(x -> x);
另外,不要使用…Async
方法,除非您希望异步执行提供的函数体。所以当你做类似的事情时
.handleAsync((x, t) -> {
if (t != null) {
return askPong("Ping");
} else {
return x;
})
您要求在单独的线程中运行
if-then-else
。由于askPong
返回一个CompletableFuture
,因此可能没有理由异步运行它。在尝试找出在Java 8中执行Scala的recoverWith的正确方法时遇到了很多挫折,我最后只编写了自己的。我仍然不知道这是否是最好的方法,但我创建了如下内容:
public RecoveryChainAsync<T> recoverWith(Function<Throwable,
CompletableFuture<T>> fn);
public RecoveryChainAsync recoverWith(函数fn);
通过反复调用recoverWith,我将恢复链中的函数排队,并使用“handle”自己实现恢复流。然后,RecoveryChainAsync.getCompletableFuture()返回整个链的代表性CompletableFuture。希望这有帮助。什么是“不正确”呢?你在寻找什么行为?那不会被编译。你不能在handleAsync中返回CompletableFuture-你必须返回U。我希望在例外情况下能够返回CompletableFuture而不是a。我正在寻找与scala或play promise recoverWith等价的函数(这与异常情况类似,但函数中的结果是异步的)。可能我没有正确使用handleAsync,但这并不意味着“并返回一个异步结果”。异常情况下,将在最初执行异步请求的线程上调用。因此,它应该已经与主执行线程异步。您是否需要重新提交给任务执行者?还是可以在同一线程上再次调用?例如,return askPong(“Ping”)。join()在异常块中仍然是异步的。我看到了您的问题,您不希望在另一个线程上执行另一个askPong时阻止发生错误的线程。除非您可以指定askPong中使用的执行器服务(然后可以重用当前线程-executor exec=(Runnable r)->r.run()),否则这太糟糕了。但它是有效的。谢谢你的解决方案!我没想到。不过这是一个黑客攻击——API中应该有一个例外的复合方法。没有,这有点令人沮丧!我可能会使用一个更好的未来接口EJAVA8库缺少很多东西。我正在开发一个名为BetterJavaMonads的库——如果你做了一个PR,如果你愿意,我可以查看你的解决方案。可能是一个有用的补充。我还为未来添加了一个遍历。嘿,谢谢顺便说一句杰夫-是的,这和我几年前遇到的完全一样,哈哈