あなたはこのようにそれを行うことができます。
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());
}
代わりの1 CompletableFuture
我々はかかるかもしれません異なる実行パスを表す2つを作成します。 loooooong操作はrunnableとして提出され、意図的にこれらのいずれかを完了しますCompletableFuture
。フォローアップステージは、満たされた条件を表すステージに連鎖され、最後に両方の実行パスが最後のapplyToEither(shortCut, Function.identity())
ステップに参加します。
shortCut
未来はすでに最終的な結果の種類を持っていると、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を使用して手動でスキップする必要があります。完全@Holgerによって提案された解決策は、素晴らしい作品、それは私にはちょっと奇妙だが、私は新しい答え
を追加しているの便宜上
ありがとうございます!同じパターン(いくつかの 'CompletableFuture'を作成し、' applyToEither(...) 'を使用)に続いて、それをいくつかのパスに拡張することができます。 – Pelocho
はい、複数のパスに拡張することができますが、結果のコードを保守しやすくするために注意する必要があります。おそらく、ブランチのロジックを複数回使用できるユーティリティメソッドにカプセル化すると便利です。 – Holger