如何创建和完成play.libs.F.Promise?

时间:2014-02-15 18:26:31

标签: java playframework-2.0 promise

我想通过调用异步第三方服务创建play.libs.F.Promise,这样我就可以链接调用并返回Promise<Result>而不是在控制器内阻塞。像这样:

final Promise<String> promise = new Promise();
service.execute(new Handler() {
  public void onSuccess(String result) {
    promise.complete(result);
  }
})
return promise;

不幸的是,似乎没有办法创建一个空play.libs.F.Promise,也没有办法来完成一个承诺?

4 个答案:

答案 0 :(得分:1)

假设当前版本的play和play.libs.F.Promise,可以通过两种方式创建promise:1)使用scala Future和Callback或2)使用play Function0(替换任何类的A) ):

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();
    }
  }
);

编辑:当您无法修改异步块时,因为它是由第三方提供的,您可以使用创建空Promise(scala promise,而不是播放框架承诺)的方法。然后你可以使用包含scala Promise的Future来生成一个play.libs.F.Promise,如下所示:

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());

答案 1 :(得分:1)

您必须使用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"));

答案 2 :(得分:0)

您可以通过执行以下操作返回空承诺:

return F.Promise.pure(null);

答案 3 :(得分:0)

您可以像这样创建F.Promise:

F.Promise<User> userPromise = F.Promise.promise(() -> getUserFromDb());

并在准备就绪时使用其值:

userPromise.onRedeem(user -> showUserData(user));