如何在传播结果或错误时调用CompletableFuture回调?

时间:2016-08-28 01:58:30

标签: java completable-future

我正在尝试.exceptionally和.handle但这些似乎不起作用。在scala中,你可以使用一个类似于finally块的闭包来调用未来的方法(它在异常AND成功时运行)并且它按原样传播异常或链成功。

我试过了......

    CompletableFuture<Object> future = newFuture.handle((r, e) -> {
        if(r != null)
            return r;
        else if(e != null)
            return e;
        else
            return new RuntimeException("Asdf");            
    });

    Assert.assertTrue(future.isCompletedExceptionally());

但该测试失败,因为未来完全成功,异常结果(多么奇怪)。

2 个答案:

答案 0 :(得分:6)

使用CompletableFuture#whenComplete(BiConsumer)。它的javadoc陈述

  

返回一个新的CompletionStage ,其结果或异常与相同   这个阶段,在这个阶段完成时执行给定的动作。

     

当这个阶段完成时,用。调用给定的动作   结果(或null如果没有)和异常(如果没有null)   阶段作为论点。操作完成后返回的阶段   回报。如果提供的操作本身遇到异常,那么   返回的阶段特别完成此异常,除非   这个阶段也完成了异常。

换句话说,无论成功与否,它都会被调用,并且会传播初始未来的状态(除非BiConsumer抛出异常)。

CompletableFuture<String> future2 = newFuture.whenComplete((r, e) -> {
    // consume the result
});

如果您需要转换结果(在您的示例中,您不会),那么您可以使用handle并自行传播内容。

答案 1 :(得分:2)

哦,哦,我想我得到了......这样的事情似乎有用了

    CompletableFuture<Integer> future2 = newFuture.handle((r, e) -> {

        //put finally like logic right here....

        if(r != null)
            return r;
        else if(e != null)
            throw new RuntimeException(e);
        else
            throw new RuntimeException("weird");
    });