5

Is there a concept of using promises in java (just like ut is used in JavaScript) instead of using nested callbacks ?

If so, is there an example of how the callback is implemented in java and handlers are chained ?

u009988
  • 394
  • 1
  • 6
  • 14
  • Are you looking for a the ability of using this in Java for Desktop/Client code, or Server based code? You should be more specific, and you will get better answers. If you are looking for a server side answer, I have one for you, but Client-Side will have to be answered by someone else.................Possible Duplicate http://stackoverflow.com/questions/14541975/difference-between-future-and-promise – XaolingBao May 24 '16 at 02:19
  • Server based code. – u009988 May 24 '16 at 02:24

3 Answers3

8

Yep! Java 8 calls it CompletableFuture. It lets you implement stuff like this.

class MyCompletableFuture<T> extends CompletableFuture<T> {

   static final Executor myExecutor = ...;

   public MyCompletableFuture() { }

   public <U> CompletableFuture<U> newIncompleteFuture() {
       return new MyCompletableFuture<U>();
   }

   public Executor defaultExecutor() {
       return myExecutor; 
   }

   public void obtrudeValue(T value) {
       throw new UnsupportedOperationException();
   }
   public void obtrudeException(Throwable ex) {
       throw new UnsupportedOperationException();
   }
}

The basic design is a semi-fluent API in which you can arrange:
        (sequential or async)
        (functions or actions)
triggered on completion of
         i) ("then") ,or
        ii) ("andThen" and "orThen")
others. As in:

MyCompletableFuture<String> f = ...; g = ...
   f.then((s -> aStringFunction(s)).thenAsync(s -> ...);
or
   f.andThen(g, (s, t) -> combineStrings).or(CompletableFuture.async(()->...)....
Debosmit Ray
  • 5,228
  • 2
  • 27
  • 43
5

UPDATE 7/20/17

I wanted to edit that there is also a Library called "ReactFX" which is supposed to be JavaFX as a reactive framework. There are many Reactive Java libraries from what I've seen, and since Play is based on the Reactive principal, I would assume that these Reactive libraries follow that same principal of non-blocking i/o, async calls from server to client and back while having communication be send by either end.

These libraries seem to be made for the client side of things, but there might be a Server reactive library as well, but I would assume that it would be wiser to use Play! with one of these client side reactive libraries.


You can take a look at https://www.playframework.com/

which implements this functionality here

https://www.playframework.com/documentation/2.2.0/api/java/play/libs/F.Promise.html


Additonal reading https://www.playframework.com/documentation/2.5.x/JavaAsync

Creating non-blocking actions

Because of the way Play works, action code must be as fast as possible, i.e., non-blocking. So what should we return from our action if we are not yet able to compute the result? We should return the promise of a result!

Java 8 provides a generic promise API called CompletionStage. A CompletionStage<Result> will eventually be redeemed with a value of type Result. By using a CompletionStage<Result> instead of a normal Result, we are able to return from our action quickly without blocking anything. Play will then serve the result as soon as the promise is redeemed.

The web client will be blocked while waiting for the response, but nothing will be blocked on the server, and server resources can be used to serve other clients.

How to create a CompletionStage

To create a CompletionStage<Result> we need another promise first: the promise that will give us the actual value we need to compute the result:

CompletionStage<Double> promiseOfPIValue = computePIAsynchronously();
CompletionStage<Result> promiseOfResult = promiseOfPIValue.thenApply(pi ->
                ok("PI value computed: " + pi)
);

Play asynchronous API methods give you a CompletionStage. This is the case when you are calling an external web service using the play.libs.WS API, or if you are using Akka to schedule asynchronous tasks or to communicate with Actors using play.libs.Akka.

A simple way to execute a block of code asynchronously and to get a CompletionStage is to use the CompletableFuture.supplyAsync() helper:

CompletionStage<Integer> promiseOfInt = CompletableFuture.supplyAsync(() -> intensiveComputation());

Note: It’s important to understand which thread code runs on which promises. Here, the intensive computation will just be run on another thread.

You can’t magically turn synchronous IO into asynchronous by wrapping it in a CompletionStage. If you can’t change the application’s architecture to avoid blocking operations, at some point that operation will have to be executed, and that thread is going to block. So in addition to enclosing the operation in a CompletionStage, it’s necessary to configure it to run in a separate execution context that has been configured with enough threads to deal with the expected concurrency. See Understanding Play thread pools for more information.

It can also be helpful to use Actors for blocking operations. Actors provide a clean model for handling timeouts and failures, setting up blocking execution contexts, and managing any state that may be associated with the service. Also Actors provide patterns like ScatterGatherFirstCompletedRouter to address simultaneous cache and database requests and allow remote execution on a cluster of backend servers. But an Actor may be overkill depending on what you need.

Async results

We have been returning Result up until now. To send an asynchronous result our action needs to return a CompletionStage<Result>:

public CompletionStage<Result> index() {
    return CompletableFuture.supplyAsync(() -> intensiveComputation())
            .thenApply(i -> ok("Got result: " + i));
}

Actions are asynchronous by default Play actions are asynchronous by default. For instance, in the controller code below, the returned Result is internally enclosed in a promise:

public Result index() {
    return ok("Got request " + request() + "!");
}

Note: Whether the action code returns a Result or a CompletionStage<Result>, both kinds of returned object are handled internally in the same way. There is a single kind of Action, which is asynchronous, and not two kinds (a synchronous one and an asynchronous one). Returning a CompletionStage is a technique for writing non-blocking code.


Some info on CompletionStage

https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/CompletionStage.html

which is a subclass of the class mentioned in @Debosmit Ray's answer called CompletableFuture


This Youtube Video by LinkedIn dev Mr. Brikman explains a bit about Promises in

https://youtu.be/8z3h4Uv9YbE?t=15m46s

and

https://www.youtube.com/watch?v=4b1XLka0UIw

I believe the first video gives an example of a promise, the second video might also give some good info, I don't really recall which video had what content.

Either way the information here is very good, and worth looking into.


I personally do not use Play, but I have been looking at it for a long, long time, as it does a lot of really good stuff.

XaolingBao
  • 1,034
  • 1
  • 18
  • 34
0

If you want to do Promise even before Java7, "java-promise" may be useful. (Of course it works with Java8)

You can easily control asynchronous operations like JavaScript's Promise.

https://github.com/riversun/java-promise

example

import org.riversun.promise.Promise;
public class Example {

    public static void main(String[] args) {
        Promise.resolve("foo")
                .then(new Promise((action, data) -> {
                    new Thread(() -> {
                        String newData = data + "bar";
                        action.resolve(newData);
                    }).start();
                }))
                .then(new Promise((action, data) -> {
                    System.out.println(data);
                    action.resolve();
                }))
                .start();
        System.out.println("Promise in Java");
    }
}

result:

Promise in Java foobar

riversun
  • 758
  • 8
  • 12