Until now, we were able to compute the result to send to the web client directly. This is not always the case: the result may depend of an expensive computation or on a long web service call.html
到目前为止,咱们能够直接计算出发送到web客户端的结果。而不会老是这样:结果须要通过耗时的计算或web service调用。java
Because of the way Play 2.0 works, action code must be as fast as possible (i.e. non blocking). So what should we return as result if we are not yet able to compute it? The response should be a promise of a result!web
play2.0要求action代码必须尽量的快(例如非阻塞),若是咱们一时还不能计算它,那么咱们应该返回什么?答案是一个结果的Promise(承诺)!后端
A Promise<Result>
will eventually be redeemed with a value of type Result
. By giving a Promise<Result>
instead of a normal Result
, we are able to compute the result quickly without blocking anything. Play will then serve this result as soon as the promise is redeemed.数组
一个 Promise<Result>
实际上最终会返回一个 Result
值。用 Promise<Result>
代替Result
,咱们就可以无阻塞的快速计算结果。一旦promise完成了,play就会返回这个结果。promise
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.服务器
web客户端在等待应答的时候会被阻塞住,可是服务器端不会阻塞,服务器还能给其余客户端提供服务.app
Promise<Result>
Promise<Result>
To create a Promise<Result>
we need another promise first: the promise that will give us the actual value we need to compute the result:异步
为了建立一个 Promise<Result>
,咱们首先须要另一个promise:这个promise将会返回一个须要计算结果的实际值:async
} );
Promise<Double> promiseOfPIValue = computePIAsynchronously(); Promise<Result> promiseOfResult = promiseOfPIValue.map( new Function<Double,Result>() { public Result apply(Double pi) { return ok("PI value computed: " + pi); }
Note: Writing functional composition in Java is really verbose for at the moment, but it should be better when Java supports lambda notation.
注意:目前在java里写函数组合很是的罗嗦,可是等java支持lamba表达式的时候状况会好一些。
Play 2.0 asynchronous API methods give you a Promise
. 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 usingplay.libs.Akka
.
当你用 play.libs.WS
API调用外部的webservice或者用AKKA调度异步任务或使用play.libs.Akka
进行异步通信时,Play 2.0异步API方法就会返回一个 Promise
.
A simple way to execute a block of code asynchronously and to get a Promise
is to use the play.libs.Akka
helpers:
异步的执行一个代码块的简单方式是使用 play.libs.Akka
便利方法:
Promise<Integer> promiseOfInt = Akka.future(
new Callable<Integer>() {
public Integer call() {
intensiveComputation();
}
} );
Note: Here, the intensive computation will just be run on another thread. It is also possible to run it remotely on a cluster of backend servers using Akka remote.
注意:这里,密集的计算会在其余线程里执行。也有可能在后端服务器集群上远程执行.
While we were using Results.Status
until now, to send an asynchronous result we need an Results.AsyncResult
that wraps the actual result:
当咱们使用 Results.Status
时,为了发送一个异步result,咱们须要一个包含了实际的result的 Results.AsyncResult
:
}
)
);
}
public static Result index() { Promise<Integer> promiseOfInt = Akka.future( new Callable<Integer>() { public Integer call() { intensiveComputation(); } } ); async( promiseOfInt.map( new Function<Integer,Result>() { public Result apply(Integer i) { return ok("Got result: " + i); }
Note:
async()
is an helper method building anAsyncResult
from aPromise<Result>
.注意:
async()
是一个根据Promise<Result>
构建AsyncResult
的便利方法。