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

Playframework 在Play Framework 2.2中使用非异步操作有什么好处吗?,playframework,playframework-2.2,Playframework,Playframework 2.2,缔约国指出: 由于游戏的工作方式,动作代码必须尽可能快(即非阻塞)。那么,如果我们还不能生成结果,我们应该返回什么呢?回应是未来的结果 未来的[Result]最终将使用Result类型的值进行赎回。通过给出未来的[结果]而不是正常的结果,我们能够快速生成结果而无需阻塞。然后,一旦承诺被兑现,游戏将为这个结果服务 web客户端将在等待响应时被阻止,但服务器上不会阻止任何内容,服务器资源可用于服务其他客户端 返回未来的操作是创建的Action.async,而不是Action.apply用于正常的非异

缔约国指出:

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

未来的[Result]最终将使用Result类型的值进行赎回。通过给出未来的[结果]而不是正常的结果,我们能够快速生成结果而无需阻塞。然后,一旦承诺被兑现,游戏将为这个结果服务

web客户端将在等待响应时被阻止,但服务器上不会阻止任何内容,服务器资源可用于服务其他客户端

返回未来的操作是创建的
Action.async
,而不是
Action.apply
用于正常的非异步操作

使用非异步操作有什么好处吗?我突然想到,确保我的任何操作都不会被阻止的最好方法是使用
Action.async
声明所有操作

事实上,根据游戏2.3中的描述,所有动作都是异步的:

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


仅仅因为您可能使用
Action.async
,并不意味着您没有阻塞。这完全取决于您是否使用了阻塞API

游戏2.2的工作方式似乎与游戏2.3的工作方式相同。除了签名之外,
Action.apply
Action.async
之间实际上没有什么区别
Action.async
需要返回
未来[Result]
的某个代码块,而
Action.apply
需要返回
结果的某个代码块<代码>操作。应用
只需调用
Future.successful(block)
即可将
block:=>Result
转换为
Future[Result]
。(在调用
Future.successful
之前,还有一些工作要做,但这就是它的要点。)

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

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

然后,控制器功能可能如下所示:

def read(id: Long) = Action {
    Ok(Json.toJson(User.read(id))
}
def read(id: Long): Future[User]
def read(id: Long) = Action.async {
    User.read(id).map(user => Ok(Json.toJson(user)))
}
这大致相当于
操作。apply
的作用:

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

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

def read(id: Long) = Action {
    Ok(Json.toJson(User.read(id))
}
def read(id: Long): Future[User]
def read(id: Long) = Action.async {
    User.read(id).map(user => Ok(Json.toJson(user)))
}
控制器功能将如下所示:

def read(id: Long) = Action {
    Ok(Json.toJson(User.read(id))
}
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邮件列表上的这个帖子是一个很好的阅读主题:

感谢您的全面回复。你提供的链接非常棒,还有youtube视频链接,我是撰写问题中引用的文本的撰稿人。我想澄清一下,本文并没有提到版本2.3中引入的新行为。更新后的文档恰巧与Play2.3一起发布,没有向后移植到以前的分支,但它也适用于版本2.x。见和。