Is there a .thenCompose() for CompletableFuture that also executes exceptionally?

霸气de小男生 提交于 2020-01-03 08:26:10

问题


I want to execute a CompletableFuture once another CompletableFuture finishes, regardless of whether or not the first one completes exceptionally (.thenCompose() only runs when execution completes normally).

For example:

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"));

This prints

ALL DONE
HERE

and I would like it to be

HERE
ALL DONE

preferably without nesting the second whenComplete() inside the first.

Note that I don't care about the returned result/exception here.


回答1:


The trick is to use .handle((r, e) -> r) to suppress the error:

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



回答2:


Maybe you should use whenCompleteAsync instead of 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());


来源:https://stackoverflow.com/questions/27576569/is-there-a-thencompose-for-completablefuture-that-also-executes-exceptionally

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!