Promises are primary building blocks in the DataKernel async programming model which can be compared to Java Futures
(CompletionStage to be more exact).
If you are not familiar with the Promises concept, the following paragraph is for you.
If otherwise, you can skip this part and move directly to the next section.
In general, Promise represents the result of an operation that hasn’t been completed yet,
but will be at some undetermined point of time in the future. It is used for deferred and asynchronous computations.
Promise is a high-performance Java Future alternative. It doesn’t only represent a future result
of an asynchronous computation, but also allows to transform and process the unspecified incoming result using a chaining
mechanism. Moreover, such results can be combined with the help of the provided combinators.
Unlike Java Future, Promises were naturally designed to work within a single eventloop thread.
They are extremely lightweight, have
no multithreading overhead, and thus are capable of processing millions of calls per second.
Using DataKernel, we can primarily manage Promises with the basic methods:
of(T value) - creates a successfully completed promise, like CompletableFuture.completedFuture().
ofException() - creates an exceptionally completed promise.
complete() - creates a successfully completed Promise<Void>, a shortcut to Promise.of(null).
Promise will succeed or fail at some unspecified time and you need to chain methods that will be executed in both cases:
then() - returns a new Promise which, when this Promise completes successfully, is executed with this Promise
as an argument, like CompletionStage.thenCompose().
map() - returns a new Promise which, when this Promise completes successfully, is executed with its result as an argument, like CompletionStage.thenApply().
whenResult() - subscribes to execute given action after this Promise completes successfully,
In addition, to handle errors the following methods are provided:
thenEx() - returns a new Promise which is executed with the Promise result as the argument when Promise completes either successfully or with an exception.
whenException() - subscribe to execute given action after this Promise completes exceptionally and returns a new Promise.
When we have multiple asynchronous calls, we need to execute them in order.
That way we can just chain methods together to create a sequence.
To run the examples, you need to clone DataKernel from GitHub:
$ git clone https://github.com/softindex/datakernel And import it as a Maven project. Check out branch v3.1. Before running the examples, build the project.
These examples are located at datakernel -> examples -> core -> promise
You can create chains of Promises even before they are completed and you don’t know yet if they will complete
successfully or with an exception. In this example we have a doSomeProcess which returns a Promise that has equal
chances to complete either successfully or with an exception. So we create a chain which will handle both cases:
If you run the example, you will receive either this output (if doSomeProcess finishes successfully):
Or this, if it finishes with an exception:
Note that the first line is
This is due to the 1 second delay we set up in doSomeProcess.
You can combine several Promises, for example:
There are also several ways to delay Promise:
Promises is a helper class which allows to efficiently manage multiple Promises. This example will demonstrate
three use cases.
1.In the following example we use the Promisesloop, which resembles Java for loop, but has async capabilities,
which are provided by Promise:
The output is:
2.Another example creates a list of Promises results using PromisestoList method:
The output is:
3.In the last example PromisestoArray method is utilized, which reduces promises to array of provided data type (in this case, Integers):