函数式 Java - whenComplete 和异常之间的交互
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/31338514/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Functional Java - Interaction between whenComplete and exceptionally
提问by peco
In this code:
在这段代码中:
doSomethingThatMightThrowAnException()
.whenComplete((result, ex) -> doSomethingElse()})
.exceptionally(ex -> handleException(ex));
When there is an exception from doSomethingThatMightThrowAnException
, are both doSomethingElse
and handleException
run, or is the exception consumed by either the whenComplete
or the exceptionally
?
当有一个例外,从doSomethingThatMightThrowAnException
,都doSomethingElse
和handleException
运行,或者是通过异常无论是消费whenComplete
还是exceptionally
?
EDIT:
编辑:
doSomethingThatMightThrowAnException
returns a CompletableFuture
, which might completeExceptionally
. This is the exception I'm talking about.
doSomethingThatMightThrowAnException
返回 a CompletableFuture
,这可能completeExceptionally
. 这是我所说的例外。
回答by Holger
The documentation of whenComplete
says:
Returns a new CompletionStage with the same result or exception as this stage, that executes the given action when this stage completes.
返回一个与此阶段具有相同结果或异常的新 CompletionStage ,在此阶段完成时执行给定的操作。
(emphasis mine)
(强调我的)
This implies that an exception is not swallowed by this stage as it is supposed to have the same result or exception. However, you might be surprised by the fact that subsequent stages will receive the exception of a previous stage wrapped within a CompletionException
, as discussed here, so it's not exactly the same exception:
这意味着该阶段不会吞下异常,因为它应该具有相同的结果或异常。但是,您可能通过这样的事实感到惊讶的是后续阶段将获得前一阶段内的包裹外CompletionException
,所讨论的在这里,所以它不是完全一样的例外:
CompletableFuture<String> test=new CompletableFuture<>();
test.whenComplete((result, ex) -> System.out.println("stage 2: "+result+"\t"+ex))
.exceptionally(ex -> { System.out.println("stage 3: "+ex); return ""; });
test.completeExceptionally(new IOException());
will print:
将打印:
stage 2: null java.io.IOException
stage 3: java.util.concurrent.CompletionException: java.io.IOException
Note that you can always append multiple actions on one stage instead of chaining then:
请注意,您始终可以在一个阶段附加多个操作,而不是链接:
CompletableFuture<String> test=new CompletableFuture<>();
test.whenComplete((result, ex) -> System.out.println("stage 2a: "+result+"\t"+ex));
test.exceptionally(ex -> { System.out.println("stage 2b: "+ex); return ""; });
test.completeExceptionally(new IOException());
stage 2b: java.io.IOException
stage 2a: null java.io.IOException
Of course, since now there is no dependency between the stage 2a
and 2b
, there is no ordering between them and in the case of async action, they may run concurrently.
当然,由于现在 stage2a
和之间没有依赖关系2b
,它们之间没有顺序,在异步操作的情况下,它们可以并发运行。
回答by OldCurmudgeon
The exceptionallymethod states:
该特别法规定:
Returns a new CompletableFuture that is completed when this CompletableFuture completes, with the result of the given function of the exception triggering this CompletableFuture's completion when it completes exceptionally; otherwise, if this CompletableFuture completes normally, then the returned CompletableFuture also completes normally with the same value. Note: More flexible versions of this functionality are available using methods whenComplete and handle.
返回一个新的 CompletableFuture,在这个 CompletableFuture 完成时完成,异常的给定函数的结果在它异常完成时触发这个 CompletableFuture 的完成;否则,如果此 CompletableFuture 正常完成,则返回的 CompletableFuture 也以相同的值正常完成。注意:使用 whenComplete 和 handle 方法可以使用此功能的更灵活版本。
This is not, IMHO written in the clearest english but I would say that means that if an exception is thrown then only the exceptionally
action will be triggered. If no exception is thrown then only the normal
action will be performed.
这不是,恕我直言用最清晰的英语写的,但我会说这意味着如果抛出异常,那么只会exceptionally
触发操作。如果没有抛出异常,则只会normal
执行该操作。
回答by Tuxxy_Thang
doSomethingThatMightThrowAnException()
is chained with .whenComplete((result, ex) -> doSomethingElse()})
and .exceptionally(ex -> handleException(ex));
but if it throws an exception it ends right there as no object will be passed on in the chain.
doSomethingThatMightThrowAnException()
与.whenComplete((result, ex) -> doSomethingElse()})
and链接,.exceptionally(ex -> handleException(ex));
但如果它抛出异常,它会在那里结束,因为链中不会传递任何对象。
Remember that an exception will throw out to the caller, so unless doSomethingThatMightThrowAnException()
catches the exception internally it will throw out. If this is your class you should know if it does throw, if not check docs for libraries that you use.
请记住,异常会抛出给调用者,因此除非doSomethingThatMightThrowAnException()
在内部捕获异常,否则它会抛出。如果这是您的课程,您应该知道它是否会抛出,如果没有,请检查您使用的库的文档。