我正在研究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的某个地方?
答案 0 :(得分:2)
javadocs说出了可以做的方法,而不是他们无法做到的无数其他事情:
public CompletionStage<T> whenComplete (BiConsumer<? super T, ? super Throwable> action);
返回具有相同结果或例外的新 CompletionStage 在这个阶段,当这个阶段完成时,执行
对结果给出动作(如果没有,则为{@code null})和
此阶段的异常(或{@code null},如果没有)
@param动作执行的动作
@return 新 CompletionStage
文档说你每次调用CompletionStage
都会创建一个新的CompleteableFuture
(whenComplete
实现),他们只提到从旧阶段到新阶段的结果的前向传播
您只能假设这些方法符合文档描述的内容。
你所期待的是从新阶段到旧阶段的向后传播,在javadoc中的任何地方都显然没有被提及,因此你不应该期待这种行为首先。