2015-05-15 7 views
1

Я изучаю Java 8 CompletableFuture (обещаю на языках, таких как Scala или JS).CompletedFuture return совершенно другое будущее

Возможно, я сделал что-то неправильно или не нашел описания этого. Будущее, которое вернулось после установки нескольких обратных вызовов, возвращает полностью независимое будущее.

У меня есть модульный тест для этого:

public class FutureTest { 
    private boolean stage1; 
    private boolean stage2; 

    @Before 
    public void setUp() throws Exception { 
     this.stage1 = false; 
     this.stage2 = false; 
    } 

    @Test 
    public void testCombinationOfCallbacks() throws Exception { 
     final CompletableFuture<String> future = new CompletableFuture<>(); 

     future 
      .whenComplete((s, e) -> stage1 = true) 
      .whenComplete((s, e) -> stage2 = true); 

     future.complete("done"); 

     assertTrue(stage1); 
     assertTrue(stage2); 
     assertEquals("done", future.get()); 
    } 

    @Test 
    public void testCombinationOfCallbacksCalledOnReturnedFuture() throws Exception { 
     final CompletableFuture<String> future = new CompletableFuture<>(); 

     final CompletableFuture<String> returnedFuture = future 
       .whenComplete((s, e) -> stage1 = true) 
       .whenComplete((s, e) -> stage2 = true); 

     returnedFuture.complete("done"); 

     assertFalse(future.isDone()); 
     assertFalse(stage1); 
     assertFalse(stage2); 
    } 
} 

Как вы можете видеть, во втором тесте, изначально созданное будущее не влияют на факте завершения будущего с обратными вызовами. Таким образом, в основном обратные вызовы настраиваются на будущее, которое было создано, но не возвращается в будущем.

Это означает, что вы никогда не сделать что-то вроде этого:

private CompletableFuture<String> createFuture() { 
    return new CompletableFuture<String>() 
     .whenComplete((s, e) -> stage1 = true) 
     .whenComplete((s, e) -> stage2 = true); 
} 

ли это документально где-то в JavaDocs?

ответ

2

В Javadocs говорит, что методы могут делать, а не бесконечное количество других вещей, которые они не могут сделать:

public CompletionStage<T> whenComplete 
    (BiConsumer<? super T, ? super Throwable> action); 

Возвращает нового CompletionStage с тем же результатом или исключениями
, и когда этот этап завершается, выполняет
данное действие с результатом (или {@code null}, если оно отсутствует) и исключение
(или {@code nul l}, если нет) этого этапа.

@param действия действия для выполнения
@return нового CompletionStage

документы говорят, вы создаете новый CompletionStage (который CompleteableFuture орудия) с каждым вызовом whenComplete, и они только упомянуть вперед - продвижение результатов от старого этапа к новому этапу.

Вы можете только предположить, что методы выполняют то, что описывают документы.

То, что вы ожидали, - это обратное распространение с новой ступени на старую сцену, в которой не упоминается в любом месте javadocs, и поэтому вы не должны ожидать этого поведения в первую очередь.

Смежные вопросы