Java 将CompletableStage与最终错误传播动态结合

Java 将CompletableStage与最终错误传播动态结合,java,completable-future,Java,Completable Future,我需要动态组合CompletionStages(基于计算结果),以避免阻塞执行,并最终需要捕获操作过程中可能出现的异常,以便仔细关闭执行 我已经实现了如下内容: 公共CompletableFuture getData(){ 最终数据累加器=新数据(); CompletableFuture结果=新建CompletableFuture(); CompletableStage exec=…//开始执行 exec.thencomposesync( (res)->过程(累加器,res) ).然后接受(t

我需要动态组合
CompletionStages
(基于计算结果),以避免阻塞执行,并最终需要捕获操作过程中可能出现的异常,以便仔细关闭执行

我已经实现了如下内容:


公共CompletableFuture getData(){
最终数据累加器=新数据();
CompletableFuture结果=新建CompletableFuture();
CompletableStage exec=…//开始执行
exec.thencomposesync(
(res)->过程(累加器,res)
).然后接受(t->result.complete(累加器));
返回结果;
}
专用完成阶段流程(数据acc、结果res){
res.data().forEach(
当前数据->{
add.addData(currData);
}
);
if(res.hasMoreData()){
返回res.fetchNextData()。然后返回ComposeAsync(
(nextData)->流程(acc,nextData)
);
}
返回CompletableFuture.completedFuture(空);
}

我不知道这是否是实施解决方案的最佳方式,但如果一切顺利,它就会起作用。当
forEach
块中由于任何原因出现异常时,就会出现问题,错误不会传播回
getData
调用方,因此我无法使用
excellective
方法捕获它,以便以安全的方式停止我的应用程序。我想我做错了什么。

当传递给
ThenComposeSync
的函数异常失败时,
ThenComposeSync
返回的未来将异常完成。这导致由链式普通操作创建的期货也异常完成,而不评估其功能

该规则有三个例外情况,仅在例外完成后进行评估,以产生替换值,而在这两种情况下都对and进行评估

因此,当您想用回退值替换异常时,可以使用

exec.thenComposeAsync(res -> process(accumulator, res))
    .exceptionally(throwable -> fallBack)
    .thenAccept(t -> result.complete(accumulator));
exec.thenComposeAsync(res -> process(accumulator, res))
    .whenComplete((value, throwable) -> {
         if(throwable == null) result.complete(accumulator);
         else result.completeExceptionally(throwable);
    });
然后接受
之前,必须小心链接
异常
,否则在异常情况下传递给
然后接受
的函数将不会得到评估

如果要将异常传播到
结果
将来,可以使用

exec.thenComposeAsync(res -> process(accumulator, res))
    .exceptionally(throwable -> fallBack)
    .thenAccept(t -> result.complete(accumulator));
exec.thenComposeAsync(res -> process(accumulator, res))
    .whenComplete((value, throwable) -> {
         if(throwable == null) result.complete(accumulator);
         else result.completeExceptionally(throwable);
    });

根据
null
检查
throwable
以确定完成是否异常非常重要,因为
值可以作为普通结果
null
。即使在普通结果值永远不能为空的情况下,也建议坚持使用惯用的解决方案,因为您不知道是否以及何时会重用代码。

当传递给
的函数出现异常而失败时,
thencomposasync
返回的future将异常完成。这导致由链式普通操作创建的期货也异常完成,而不评估其功能

该规则有三个例外情况,仅在例外完成后进行评估,以产生替换值,而在这两种情况下都对and进行评估

因此,当您想用回退值替换异常时,可以使用

exec.thenComposeAsync(res -> process(accumulator, res))
    .exceptionally(throwable -> fallBack)
    .thenAccept(t -> result.complete(accumulator));
exec.thenComposeAsync(res -> process(accumulator, res))
    .whenComplete((value, throwable) -> {
         if(throwable == null) result.complete(accumulator);
         else result.completeExceptionally(throwable);
    });
然后接受
之前,必须小心链接
异常
,否则在异常情况下传递给
然后接受
的函数将不会得到评估

如果要将异常传播到
结果
将来,可以使用

exec.thenComposeAsync(res -> process(accumulator, res))
    .exceptionally(throwable -> fallBack)
    .thenAccept(t -> result.complete(accumulator));
exec.thenComposeAsync(res -> process(accumulator, res))
    .whenComplete((value, throwable) -> {
         if(throwable == null) result.complete(accumulator);
         else result.completeExceptionally(throwable);
    });

根据
null
检查
throwable
以确定完成是否异常非常重要,因为
值可以作为普通结果
null
。即使在普通结果值永远不能为空的情况下,也建议坚持使用惯用的解决方案,因为您不知道是否以及何时将重用代码。

报告的代码只是一个片段,说明我正在尝试做什么以及问题出在哪里。代码无法编译,因为大部分部分都丢失了。我不知道你想做什么。但我确实注意到了你的“如果一切都好,它就会起作用”。我不知道我的解决方案是否正确。一切顺利时,它运行良好。我的问题与异常有关。当
forEach
中发生异常时,我无法在
getData
@Holger的调用方上捕获它,您的解决方案很有用。为什么不把它放在一个答案里?@Scratte我做了一个答案报告的代码只是一个片段,用来说明我想做什么,以及问题出在哪里。代码无法编译,因为大部分部分都丢失了。我不知道你想做什么。但我确实注意到了你的“如果一切都好,它就会起作用”。我不知道我的解决方案是否正确。一切顺利时,它运行良好。我的问题与异常有关。当
forEach
中发生异常时,我无法在
getData
@Holger的调用方上捕获它,您的解决方案很有用。为什么不把它写进一个答案里呢?@Scratte我做了一个答案