Imagine the simple case, you do action A
, when it is complicated, do B
with the result of A
operation - be that a Throwable
or a valid result. Add to that that there is no CompletableFuture
yet, and you do not want to block. Is it doable with Future
s only? Well, yes. Is it painful to achieve? Very.
Do not get fooled by the "simplicity" of its API. In your previous question you already saw what not specifying an ExecutorService
to some actions does. There are many, many more subtle things that comes with the package of that "simplicity".
The non-blocking capabilities of CompletableFuture
made it highly usable and highly adopted by the developers. Not only us, usual developers, but the jdk ones too - the entire jdk http client is build around CompletableFuture
, for a reason.
And your question is not vs ExecutorService
, but should really be vs Future
. An ExecutorService
can still be passed to methods that CompletableFuture
provides. For example read this Q&A for what various methods do and act like.