Böyle yapabilirsiniz:
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());
}
Yerine biri CompletableFuture
biz alabilir farklı bir yürütme yolları temsil eden iki oluşturun. Loooooong işlemi, daha sonra çalıştırılabilir olarak sunulur ve bu CompletableFuture
'dan birini bilinçli olarak tamamlar. Takip aşamaları, yerine getirilen koşulu temsil eden aşamaya zincirlenir, daha sonra her iki yürütme yolu da son applyToEither(shortCut, Function.identity())
adımında birleştirilir.
shortCut
gelecek zaten nihai sonucun türü olan ve RESULT_1
ile tamamlanmış olacak, tüm operasyonun hemen tamamlandığını neden olacaktır null
geçen yolun, sonucudur. İlk aşamada ve kısa kesim gerçek sonuç değeri arasındaki bağımlılık beğenmezseniz, böyle geri çekebilirsiniz:
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());
}
üçüncü basamak örnek değildi ama tam olarak böyle gösterilir görünüyorsa söz konusu, kod yolu katılmadan adımla bunu birleştirebilir:
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);
}
sonra yalnızca ikinci adımı, someMethodThatReturnsACompletionStage
çağırmayı atlıyor ancak bu yine de, ara adımların uzun zinciri için durabiliriz, tüm olmadan atlanır nullcheck ile manuel bir atlama yapmak gerekiyor. tamlığı @Holger önerdiği çözüm inşaat büyük benim için biraz garip olsa da yeni bir cevap
ekliyorum uğruna
Çalışır, teşekkürler! Aynı kalıbı takip ederek (birkaç CompletableFuture işlevi oluşturulduğunda ve applyToEither (...) 'yi kullanarak) onu çeşitli yollara genişletmek mümkün olabilir, değil mi? – Pelocho
Evet, bunu birden fazla yola genişletebilirsiniz, ancak ortaya çıkan kodun bakımını yapmaya devam etmelisiniz. Belki de, bir dalın mantığını, birçok kez kullanabileceğiniz bir yardımcı program biçiminde kapsüllemeye yardımcı olur. – Holger