2014-12-20 1 views
4

Я хочу выполнить CompletableFuture один раз другой CompletableFuture заканчивается, независимо от того, завершился ли первый из них исключительно (.thenCompose() запускается только при завершении выполнения).Есть ли. ThenCompose() для CompletedFuture, который также выполняется исключительно?

Например:

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() внутри первого.

Обратите внимание, что здесь меня не интересует возвращенный результат/исключение.

ответ

5

Хитрость заключается в том, чтобы использовать .handle((r, e) -> r) подавить ошибку:

CompletableFuture.runAsync(() -> { throw new RuntimeException(); }) 
    //Suppress error 
    .handle((r, e) -> r) 
    .thenCompose((r) -> 
     CompletableFuture.runAsync(() -> System.out.println("HELLO"))); 
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()); 
Смежные вопросы