CompletableFuture回归完全不同的未来

时间:2015-05-15 20:01:28

标签: java-8 future

我正在研究Java 8 CompletableFuture(像Scala或JS这样的语言中的Promise)。

可能是我做错了什么或者没有找到任何关于此的描述。在设置几个回调之后返回的未来将完全独立于未来。

我有一些单元测试:

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的某个地方?

1 个答案:

答案 0 :(得分:2)

javadocs说出了可以做的方法,而不是他们无法做到的无数其他事情:

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

返回具有相同结果或例外的 CompletionStage   在这个阶段,当这个阶段完成时,执行
  对结果给出动作(如果没有,则为{@code null})和
  此阶段的异常(或{@code null},如果没有)   
  @param动作执行的动作
  @return CompletionStage

文档说你每次调用CompletionStage都会创建一个新的CompleteableFuturewhenComplete实现),他们只提到从旧阶段到新阶段的结果的前向传播

您只能假设这些方法符合文档描述的内容。

你所期待的是从新阶段到旧阶段的向后传播,在javadoc中的任何地方都显然没有被提及,因此你不应该期待这种行为首先。