Reputation: 3614
I'd like to create a play.libs.F.Promise
from a call to an async third-party service so I can chain the call and return a Promise<Result>
instead of blocking inside the controller. Something like so:
final Promise<String> promise = new Promise();
service.execute(new Handler() {
public void onSuccess(String result) {
promise.complete(result);
}
})
return promise;
Unfortunately, there does not appear to be a way to create an empty play.libs.F.Promise
, and there is no method to complete a promise, either?
Upvotes: 3
Views: 5829
Reputation: 10180
You can create F.Promise like this:
F.Promise<User> userPromise = F.Promise.promise(() -> getUserFromDb());
and use its value when it is ready:
userPromise.onRedeem(user -> showUserData(user));
Upvotes: 0
Reputation: 46
You have to use a F.RedeemablePromise.
RedeemablePromise<String> promise = RedeemablePromise.empty();
promise.map(string ->
// This would apply once the redeemable promise succeed
ok(string + " World!")
);
// In another thread, you now may complete the RedeemablePromise.
promise.success("Hello");
// OR you can fail the promise
promise.failure(new Exception("Problem"));
Upvotes: 1
Reputation: 1
You can return empty promise by doing the following:
return F.Promise.pure(null);
Upvotes: 0
Reputation: 2086
Assuming the current version of play and the play.libs.F.Promise, a promise can be created in two ways: 1) Using a scala Future and Callback or 2) using a play Function0 (replace A for any class):
import static akka.dispatch.Futures.future;
//Using 1)
Promise<A> promise=Promise.wrap(future(
new Callable<A>() {
public A call() {
//Do whatever
return new A();
}
}, Akka.system().dispatcher()));
//Using 2) - This is described in the Play 2.2.1 Documentation
// http://www.playframework.com/documentation/2.2.1/JavaAsync
Promise<A> promise2= Promise.promise(
new Function0<A>() {
public A apply() {
//Do whatever
return new A();
}
}
);
EDIT: When you can't modify the async block because it's provided by a third party you can use the approach of creating an empty Promise (scala promise, not play framework promise). Then you can use the Future containing the scala Promise to generate a play.libs.F.Promise as follows:
import akka.dispatch.Futures;
final scala.concurrent.Promise<String> promise = Futures.promise();
service.execute(new Handler() {
public void onSuccess(String result) {
promise.success(result);
}
})
return Promise.wrap(promise.future());
Upvotes: 1