I have a question regarding CompletableFuture in Java. I'm waiting for a CompletableFuture to complete and depending on the received result, I want to either call a new task and wait for the CompletableFuture to complete or do something different. I'm not happy with my solution since there are so many callbacks and it is different to read. Could you help my to improve my code?
final CompletableFuture<String> future = new CompletableFuture<>();
final ActorRef processCheckActor = actorSystem.actorOf(
springExtension.props("ProcessCheckActor"), "processCheckActor-" + new Random().nextInt());
final CompletableFuture<Object> checkResponse =
PatternsCS.ask(processCheckActor, new ProcessToCheckMessage(processId), TIMEOUT)
.toCompletableFuture();
checkResponse.thenAccept(obj -> {
final ProcessCheckResponseMessage msg = (ProcessCheckResponseMessage) obj;
if (msg.isCorrect()) {
final CompletableFuture<Object> response =
PatternsCS.ask(processSupervisorActor, new ProcessStartMessage(processId), TIMEOUT)
.toCompletableFuture();
response.thenAccept(obj2 -> {
future.complete("yes");
});
} else {
future.complete("no");
}
});
First of all, you should avoid creating a CompletableFuture<Object>
. The generic type should be the type your function returns (CompletableFuture<ProcessCheckResponseMessage>
in your case). That way you don't need the cast.
I would suggest using thenApply
rather than thenAccept
. This will create the second CompletableFuture for you, meaning you no longer need the declaration in the first line.
Finally, as a general rule, you should think twice about multi-line lambdas, and definitely avoid nested lambdas. You should consider creating a new method for these lambdas instead.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With