我对Action
和Action.async
的使用感到困惑。什么是使用它的适当条件。
我用Action.async
编写了一个带有for循环的方法,需要12秒才能处理:
def asyncIndex() = Action.async {
val time = Calendar.getInstance().get(Calendar.SECOND)
Future {
for(i<- 0 to 20000000) {
print(i)
}
Ok(Json.toJson(time))
}
}
当我同时向此方法发出两个请求时,第二个请求将被阻止,直到第一个请求完成。
PS: - 我想我还没有理解关于异步调用的正确概念。
答案 0 :(得分:2)
我对Action和Action.async很困惑,使用一个
的适当条件是什么
注意:
Action.apply
和Action.async
创建Action
对象,这些对象以相同的方式在内部处理。有一种Action
,它是异步的,而不是两种(同步的和异步的)。.async
构建器只是简化基于返回Future
的API创建操作的工具,这使得编写非阻塞代码变得更加容易。
当我同时向此方法发出两个请求时,第二个请求将被阻止,直到第一个请求完成
同样来自documentation:
在等待响应时将阻止Web客户端,但服务器上不会阻止任何内容,服务器资源可用于为其他客户端提供服务。
如果您的同时请求来自同一个同步客户端,则客户端上的其中一个请求将被阻止,直到另一个请求完成为止。服务器端没有阻塞。要实现对同一端点的请求的并行处理,请使用不同的客户端来发出这些请求,或使用进行异步HTTP调用的客户端。还要考虑为此端点使用单独的调度程序,即使您将处理包装在Future
内(有关创建自定义调度程序的更多信息也在链接文档中)。
答案 1 :(得分:0)
代码中的等待块创建了等待时间:使用Future
正文编写的代码不是完全并发的,因为在发送Ok
之前有一个循环响应;很明显,当您发送呼叫时,需要一些时间来获得第二个响应。如果您删除for循环并发送呼叫数量(例如通过curl
),您将看到应用程序正在运行而没有等待&#34;等待&#34;时间。当然这有局限性;这是你的机器的规格(cpu,ram等)。所以,单独使用Action.async
并在其中写入等待/阻塞;并不能使整个代码并发。
何时使用:有一个简单的规则:如果您的控制器的方法体中包含并发代码,那么该操作应定义为Action.async{...}
;如果不是Action{...}
。
请注意,在Play all actions are asynchronous中。