你可以这样做:
public CompletionStage<SomeResult> someMethod(SomeArgument someArgument) {
CompletableFuture<SomeResult> shortCut = new CompletableFuture<>();
CompletableFuture<ResultOfFirstOp> withChain = new CompletableFuture<>();
CompletableFuture.runAsync(() -> {
// loooooong operation
if (someCondition)
withChain.complete(validValue);
else
shortCut.complete(SomeResult.RESULT_1);
});
return withChain
.thenCompose(result -> someMethodThatReturnsACompletionStage(result))
.thenApply(result ->
result.someCondition()? SomeResult.RESULT_2: SomeResult.RESULT_3)
.applyToEither(shortCut, Function.identity());
}
我们创建了两个,而不是一个CompletableFuture
,代表我们可能采用的不同执行路径。loooooong 操作被提交为可运行的,并将故意完成其中之一CompletableFuture
。后续阶段链接到表示满足条件的阶段,然后两个执行路径在最后applyToEither(shortCut, Function.identity())
一步连接。
shortCut
future 已经有了最终结果的类型,会用你的传递路径的结果来完成,RESULT_1
这null
会导致整个操作立即完成。如果你不喜欢第一阶段和捷径的实际结果值之间的依赖关系,你可以像这样收回它:
public CompletionStage<SomeResult> someMethod(SomeArgument someArgument) {
CompletableFuture<Object> shortCut = new CompletableFuture<>();
CompletableFuture<ResultOfFirstOp> withChain = new CompletableFuture<>();
CompletableFuture.runAsync(() -> {
// loooooong operation
if (someCondition)
withChain.complete(validValue);
else
shortCut.complete(null);
});
return withChain
.thenCompose(result -> someMethodThatReturnsACompletionStage(result))
.thenApply(result ->
result.someCondition()? SomeResult.RESULT_2: SomeResult.RESULT_3)
.applyToEither(shortCut.thenApply(x -> SomeResult.RESULT_1), Function.identity());
}
如果您的第三步不是示例性的,但看起来与问题中显示的完全一样,您可以将其与代码路径连接步骤合并:
public CompletionStage<SomeResult> someMethod(SomeArgument someArgument) {
CompletableFuture<ResultOfSecondOp> shortCut = new CompletableFuture<>();
CompletableFuture<ResultOfFirstOp> withChain = new CompletableFuture<>();
CompletableFuture.runAsync(() -> {
// loooooong operation
if (someCondition)
withChain.complete(validValue);
else
shortCut.complete(null);
});
return withChain
.thenCompose(result -> someMethodThatReturnsACompletionStage(result))
.applyToEither(shortCut, result -> result==null? SomeResult.RESULT_1:
result.someCondition()? SomeResult.RESULT_2: SomeResult.RESULT_3);
}
然后我们只跳过第二步,即someMethodThatReturnsACompletionStage
调用,但这仍然可以代表一长串中间步骤,所有步骤都被跳过,而无需通过 nullcheck 推出手动跳过。