简体   繁体   English

CompletableFuture recoverWith 等价物? 即异常但返回 CompletableFuture

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

I don't see an obvious way to handle an exception with an asynchronous result.我没有看到一种明显的方法来处理具有异步结果的异常。

For example, if I want to retry an async operation, I would expect something like this:例如,如果我想重试异步操作,我会期待这样的事情:

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

Where askPong asks an actor: askPong 问演员的地方:

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

However handleAsync doesn't do what you think it does - it runs the callbacks on another thread asynchronously.但是, handleAsync并没有按照您的想法执行 - 它在另一个线程上异步运行回调。 Returning a CompletionStage here is not correct.在此处返回CompletionStage是不正确的。

Jeopardy question of the day: thenApply is to thenCompose as exceptionally is to what?当天的危险问题: thenApplythenCompose exceptionally是什么?

Is this what you are looking for?这是你想要的?

askPong("cause error")
        .handle( (pong, ex) -> ex == null 
                ? CompletableFuture.completedFuture(pong) 
                : askPong("Ping")
        ).thenCompose(x -> x);

Also, do not use the ...Async methods unless you intend for the body of the supplied function to be executed asynchronously.此外,不要使用...Async方法,除非您打算异步执行所提供函数的主体。 So when you do something like所以当你做类似的事情时

.handleAsync((x, t) -> {
    if (t != null) {
        return askPong("Ping");
    } else {
        return x;
    })

You are asking for the if-then-else to be run in a separate thread.您要求if-then-else在单独的线程中运行。 Since askPong returns a CompletableFuture , there's probably no reason to run it asynchronously.由于askPong返回CompletableFuture ,因此可能没有理由异步运行它。

Jeopardy question of the day: thenApply is to thenCompose as exceptionally is to what?当天的危险问题: thenApplythenCompose exceptionally是什么?

I know this was initially , but, since , the answer would be exceptionallyCompose :我知道这最初是 ,但是,由于 ,答案将是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.返回一个新的 CompletionStage,当此阶段异常完成时,它使用应用于此阶段异常的提供函数的结果组成。

As the JavaDoc indicates, the default implementation is:正如 JavaDoc 所示,默认实现是:

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

That is, using handle() to call the fallback, and thenCompose() to unwrap the resulting nested CompletableFuture<CompletableFuture<T>> – ie, what you would have done in previous versions of Java (like in Misha's answer ), except you would have to replace this with completedFuture(r) .也就是说,使用handle()调用回退,然后thenCompose()解包生成的嵌套CompletableFuture<CompletableFuture<T>> - 即,您在以前的 Java 版本中会执行的操作(如Misha 的答案),除了您必须用completedFuture(r)替换this

After a lot of frustration in trying to figure out the proper way of doing Scala's recoverWith in Java 8, I ended up just writing my own.在试图找出在 Java 8 中执行 Scala 的 recoveryWith 的正确方法时遇到了很多挫折之后,我最终只编写了自己的。 I still don't know if this is the best approach, but I created something like:我仍然不知道这是否是最好的方法,但我创建了类似的东西:

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

With repeated calls to recoverWith, I queue up the functions inside the recovery chain and implement the recovery flow myself with "handle".通过重复调用recoverWith,我将恢复链中的函数排入队列,并使用“句柄”自己实现恢复流程。 RecoveryChainAsync.getCompletableFuture() then returns a representative CompletableFuture for the entire chain. RecoveryChainAsync.getCompletableFuture() 然后返回整个链的代表 CompletableFuture。 Hope this helps.希望这可以帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 CompletableFuture然后在异常之后撰写 - CompletableFuture thenCompose after exceptionally 是否还有针对CompletableFuture的.thenCompose(),它也会异常执行? - Is there a .thenCompose() for CompletableFuture that also executes exceptionally? CompletableFuture exceptionly() 和 handle() 吞下 RuntimeException? - CompletableFuture exceptionally() and handle() swallowing RuntimeException? 返回CompletableFuture <Void>或CompletableFuture <?>? - Return CompletableFuture<Void> or CompletableFuture<?>? 从 CompletableFuture 异常子句中抛出异常 - Throwing exceptions from within CompletableFuture exceptionally clause CompletableFuture#exceptionally 重新抛出已检查的异常 - CompletableFuture#exceptionally rethrow checked exception 让 CompletableFuture 异常()处理 supplyAsync() 异常 - Letting CompletableFuture exceptionally() handle a supplyAsync() Exception 无法从 CompletableFuture 中异常传播自定义异常 - Unable to propagate custom exception from exceptionally in CompletableFuture 简单的 completableFuture.exceptionally() 完成时不触发 exception() - simple completableFuture.exceptionally() not triggered when completing exceptionally() 传递给 CompletableFuture.exceptionally() 的异常处理程序是否必须返回一个有意义的值? - Does an exception handler passed to CompletableFuture.exceptionally() have to return a meaningful value?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM