playframework - 在 Play Framework 2.2 中使用非异步操作有什么好处吗?

标签 playframework playframework-2.2

Play 2.2 documentation指出:

Because of the way Play works, the action code must be as fast as possible (ie. non blocking). So what should we return as result if we are not yet able to generate it? The response is a future result!

A Future[Result] will eventually be redeemed with a value of type Result. By giving a Future[Result] instead of a normal Result, we are able to quickly generate the result without blocking. Then, Play will serve this 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.


创建返回 Future 的操作 Action.async ,而不是 Action.apply对于正常的非异步操作。
使用非异步操作有什么好处吗?令我震惊的是,确保我的任何操作都不会被阻止的最佳方法是使用 Action.async 声明所有操作。 .
事实上,根据 Play Framework 2.3 documentation看起来在 Play 2.3 中所有 Action 都是异步的:

Note: Both Action.apply and Action.async create Action objects that 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). The .async builder is just a facility to simplify creating actions based on APIs that return a Future, which makes it easier to write non-blocking code.

最佳答案

只是因为你可能会使用 Action.async ,并不自动意味着您没有阻止。这完全取决于您是否使用阻塞 API。

Play 2.2 似乎以这种方式与 Play 2.3 工作方式相同。 Action.apply 之间没有真正的区别和 Action.async , 除了他们的签名。 Action.async期望一些返回 Future[Result] 的代码块, 而 Action.apply期望返回 Result 的代码块. Action.apply转换 block: => Result进入 Future[Result]只需调用 Future.successful(block) . (在调用 Future.successful 之前还有一些工作要做,但这是它的要点。)

因此,每个用例都归结为您正在使用的 API。例如 JDBC 与 ScalikeJDBC-async ,阻塞与非阻塞数据库 API。假设您正在从数据库中获取用户并将其作为 json 发送回客户端。

典型的 JDBC 支持函数的签名可能如下所示(忽略简化失败):

def read(id: Long): User

您的 Controller 功能可能如下所示:
def read(id: Long) = Action {
    Ok(Json.toJson(User.read(id))
}

这大致相当于Action.apply做:
def read(id: Long) = Action.async {
    Future.successful(Ok(Json.toJson(User.read(id)))
}
User.read然而,它仍然是一个阻塞的 JDBC 调用,所以这并不比以前更好。

现在假设我们正在使用如下所示的异步 DB 调用:
def read(id: Long): Future[User]

Controller 函数看起来像这样:
def read(id: Long) = Action.async {
    User.read(id).map(user => Ok(Json.toJson(user)))
}

可以将其更多地视为使用返回 Future 的 API 的助手。 s。真正的好处来自这些 API 的实际异步实现。如果您遇到阻塞 API(可能是 JDBC),还有其他方法可以管理它。 Play 邮件列表上的这个帖子是一个很好的阅读主题:https://groups.google.com/forum/#!topic/play-framework/WWQ0HeLDOjg

关于playframework - 在 Play Framework 2.2 中使用非异步操作有什么好处吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23997418/

相关文章:

java - 在 Play Web 服务中使用 GET 参数?

java - Play!Framework 中的批量 HTTP 请求

java - play.libs.WS.WSRequestHolder.get() 切断部分请求?

angularjs - 使用 AngularJs 处理 Play scala 发送的分块数据

database - 在 application.conf 中为 Play 2.0/anorm 加密数据库密码

scala - 游戏中的模拟对象[2.0]

scala-2.10 - 在 Play 2.2.1 框架中使用 BodyParser 和经过身份验证的请求

java - Play框架使用Apache Commons发送电子邮件

java - 在两个 Play Framework 应用程序之间共享模型的最佳方式是什么?

postgresql - 如果参数为 None,则不向服务器传递任何内容(非空)