在Play Framework 2.2中使用非异步操作有什么好处? [英] Are there any benefits in using non-async actions in Play Framework 2.2?

查看:80
本文介绍了在Play Framework 2.2中使用非异步操作有什么好处?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

播放2.2文档指出:

由于Play的工作方式,操作代码必须尽可能快(即非阻塞).那么,如果我们还不能生成结果,那我们应该返回什么呢?反应是未来的结果!

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!

Future [Result]最终将使用Result类型的值进行兑换.通过提供Future [Result]而不是普通的Result,我们可以快速生成结果而不会阻塞.然后,只要兑现承诺,Play就会提供此结果.

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.

在等待响应时,Web客户端将被阻止,但是服务器上不会阻止任何内容,并且服务器资源可用于为其他客户端提供服务.

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.async.

Actions that return a Future are created Action.async, as opposed to Action.apply for normal, non-async actions.

使用非异步动作有什么好处吗?让我惊讶的是,确保我的所有动作都不会被阻止的最好方法是使用Action.async声明所有动作.

Is there any benefit on having non-async Actions? It strikes me that the best way to ensure that none of my Actions are going to block is to declare all of them using Action.async.

实际上,根据 Play Framework 2.3文档,它看起来像在播放2.3所有动作都是异步的:

In fact, according to the Play Framework 2.3 documentation it looks like in Play 2.3 all actions are async:

注意:Action.apply和Action.async都创建在内部以相同方式处理的Action对象.有一种动作是异步的,而不是两种(同步动作和异步动作). .async构建器只是一种工具,可简化基于返回Future的API的创建动作的过程,从而使编写非阻塞代码更加容易.

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.

Just because you might use Action.async, doesn't automatically mean you're not blocking. It all depends on whether you're using blocking API or not.

Play 2.2似乎以这种方式与Play 2.3相同.除了签名之外,Action.applyAction.async之间并没有什么区别. Action.async期望返回一个Future[Result]的代码块,而Action.apply期望返回一个Result的代码块. Action.apply只需调用Future.successful(block)即可将block: => Result转换为Future[Result]. (在调用Future.successful之前,还有更多工作要做,但这是要点.)

Play 2.2 seems to work the same way as Play 2.3 in this manner. There isn't really a difference between Action.apply and Action.async, other than their signatures. Action.async expects some block of code that returns a Future[Result], while Action.apply expects a block of code that returns a Result. Action.apply converts that block: => Result into Future[Result] by simply calling Future.successful(block). (There is a little more work that goes on before calling Future.successful, but this is the gist of it.)

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

So the use cases for each boil down to the API you're using. For example JDBC vs ScalikeJDBC-async, blocking vs. non-blocking database APIs. Let's say you're fetching a user from the database and sending it back to the client as json.

典型的JDBC支持的函数的签名可能看起来像这样(忽略简化的失败):

The signature of a typical JDBC-backed function might look like this (ignoring failures to simplify):

def read(id: Long): User

您的控制器功能可能如下所示:

Your controller function might then look like this:

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调用,因此,这并不比以前更好.

User.read is still a blocking JDBC call, however, so this is no better than before.

现在让我们说我们正在使用一个异步DB调用,它看起来像这样:

Now let's say we're using an asynchronous DB call that looks something like this:

def read(id: Long): Future[User]

控制器功能如下所示:

def read(id: Long) = Action.async {
    User.read(id).map(user => Ok(Json.toJson(user)))
}

将其视为使用返回Future s的API的帮助者.真正的好处来自这些API的实际异步实现.如果您不愿意使用阻塞API(可能是JDBC),也可以使用其他方法进行管理. Play邮件列表中的该主题非常适合您阅读以下主题: https: //groups.google.com/forum/#!topic/play-framework/WWQ0HeLDOjg

Think of it as more of a helper for using APIs that return Futures. The real benefits come from actual asynchronous implementations of those APIs. If you're stuck with blocking API (probably JDBC), there are other ways to manage that as well. This thread on the Play mailing list is a good read on the subject: https://groups.google.com/forum/#!topic/play-framework/WWQ0HeLDOjg

这篇关于在Play Framework 2.2中使用非异步操作有什么好处?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆