是否还有针对CompletableFuture的.thenCompose(),它也会异常执行?

时间:2014-12-20 03:09:08

标签: java concurrency java.util.concurrent

我想在另一个CompletableFuture完成后执行CompletableFuture,无论第一个是否异常完成(.thenCompose()仅在执行正常执行时运行。)

例如:

CompletableFuture.supplyAsync(() -> 1L)
    .whenComplete((v, e) -> CompletableFuture.runAsync(() -> { 
        try {
            Thread.sleep(1000);
            System.out.println("HERE");
        } catch(InterruptedException exc) {
            return;
        }
    }))
    .whenComplete((v, e) -> System.out.println("ALL DONE"));

打印

ALL DONE
HERE

我希望它是

HERE
ALL DONE

最好不要将第二个whenComplete()嵌套在第一个内。

请注意,我不关心返回的结果/异常。

2 个答案:

答案 0 :(得分:8)

诀窍是使用.handle((r, e) -> r)来抑制错误:

CompletableFuture.runAsync(() -> { throw new RuntimeException(); })
    //Suppress error
    .handle((r, e) -> r)
    .thenCompose((r) -> 
         CompletableFuture.runAsync(() -> System.out.println("HELLO")));

答案 1 :(得分:0)

也许您应该使用whenCompleteAsync而不是CompletableFuture.runAsync:

    CompletableFuture<Long> cf = CompletableFuture.supplyAsync(() -> 1L)
    .whenCompleteAsync((v, e) -> { 
        try {
            Thread.sleep(1000);
            System.out.println("HERE");
        } catch(InterruptedException exc) {
            //nothing
        }
        //check that thowing an exception also executes the next cf
        throw new RuntimeException("exception");
    })
    .whenCompleteAsync((v, e) -> System.out.println("ALL DONE (exception thrown: " + e + ")"));

    System.out.println("CF code finished");
    System.out.println(cf.get());