2016-08-28 22 views
2

我在嘗試.exceptionally和.handle,但這些似乎並沒有工作。在scala中,你可以通過一個閉包來調用未來的方法,就像finally塊(它在異常和成功時運行),並且按照原樣傳播異常或成功鏈接。如何在傳播結果或錯誤時調用CompletableFuture回調?

我想這...

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

但測試失敗作爲未來完全成功,出現異常的結果(如何怪異)。

+0

爲了在'handle()'中正確地傳播異常,你需要拋出它們。否則,如果你只是想要副作用而不改變結果,那麼說明你應該使用'whenComplete'的答案是最好的方法。 – acelent

回答

3

使用CompletableFuture#whenComplete(BiConsumer)。它的javadoc狀態

返回一個新CompletionStage具有相同的結果或異常作爲 這個階段,這個階段完成時執行給定的動作。

當這個階段完成時,給定的動作與 結果調用(或null如果沒有)和異常(或null如果無)這個階段 作爲參數。返回的階段在動作 返回時完成。如果提供的操作本身遇到異常,則返回的階段異常完成,除非此例外 異常完成。

換句話說,無論成功或失敗它都會被調用,並會傳播最初的未來狀態(除非BiConsumer引發異常)。

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

如果你需要轉換的結果(在你的榜樣,你沒有),那麼你可以使用handle和傳播自己的東西。

0

ohhhhh,我想我明白了....這樣的事情似乎工作

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"); 
    }); 
相關問題