CompletableFuture recoverWith 等效?即异常但 return CompletableFuture<U>

CompletableFuture recoverWith equivalent? i.e. exceptionally but return CompletableFuture<U>

我没有看到处理具有异步结果的异常的明显方法。

例如,如果我想重试一个异步操作,我会期待这样的事情:

CompletionStage<String> cf = askPong("cause error").handleAsync((x, t) -> {
    if (t != null) {
        return askPong("Ping");
    } else {
        return x;
    }
});

askPong 询问演员的地方:

public CompletionStage<String> askPong(String message){
    Future sFuture = ask(actorRef, message, 1000);
    final CompletionStage<String> cs = toJava(sFuture);
    return cs;
} 

但是 handleAsync 并没有像您想象的那样做 - 它在另一个线程上异步运行回调。这里返回一个CompletionStage是不正确的。

今日危险问题:thenApply 之于 thenCompose 如同 exceptionally 之于什么?

这是您要找的吗?

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 returns 一个 CompletableFuture,可能没有理由 运行 它是异步的。

在尝试找出在 Java 8 中执行 Scala 的 recoverWith 的正确方法时遇到很多挫折之后,我最终只写了自己的。我仍然不知道这是否是最好的方法,但我创建了类似的东西:

public RecoveryChainAsync<T> recoverWith(Function<Throwable,
                                         CompletableFuture<T>> fn);

通过重复调用 recoverWith,我将恢复链中的函数排队,并使用 "handle" 自己实现恢复流程。 RecoveryChainAsync.getCompletableFuture() 然后 returns 代表整个链的 CompletableFuture。希望这有帮助。

Jeopardy question of the day: thenApply is to thenCompose as exceptionally is to what?

我知道这最初是 , but, since ,答案是 exceptionallyCompose:

exceptionallyCompose[Async](Function<Throwable,? extends CompletionStage<T>> fn [, Executor executor])

Returns a new CompletionStage that, when this stage completes exceptionally, is composed using the results of the supplied function applied to this stage's exception.

如 JavaDoc 所示,默认实现是:

return handle((r, ex) -> (ex == null)
              ? this
              : fn.apply(ex))
    .thenCompose(Function.identity());

也就是说,使用 handle() 调用回退,并使用 thenCompose() 解包结果嵌套 CompletableFuture<CompletableFuture<T>> – 即,您在以前版本的 [=31] 中所做的=](就像在 中一样),除了您必须将 this 替换为 completedFuture(r).