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
的便利方法。