async Action api在play framework 2.2.x for scala中是如何工作的?

async Action api在play framework 2.2.x for scala中是如何工作的?,scala,asynchronous,playframework,playframework-2.0,akka,Scala,Asynchronous,Playframework,Playframework 2.0,Akka,我试图创建异步api。但响应显示顺序执行。 完成步骤:在chrome的两个选项卡中打开url。很快一个接一个地打他们。url ex:-localhost:9000/getStar 但执行日志如下所示:- [info] play - Listening for HTTP on /0:0:0:0:0:0:0:0:9000 (Server started, use Ctrl+D to stop and go back to the console...) [success] Compile

我试图创建异步api。但响应显示顺序执行。 完成步骤:在chrome的两个选项卡中打开url。很快一个接一个地打他们。url ex:-localhost:9000/getStar

但执行日志如下所示:-

    [info] play - Listening for HTTP on /0:0:0:0:0:0:0:0:9000

(Server started, use Ctrl+D to stop and go back to the console...)

[success] Compiled in 107ms
[info] application - Application has started
[info] play - Application started (Dev)
[info] application - Async started ************************** :tarun
[info] application - Success Async call  :1
[info] application - Success Async call  :2
[info] application - Success Async call  :3
[info] application - Success Async call  :4
[info] application - Success Async call  :5
[info] application - Success Async call  :6
[info] application - Success Async call  :7
[info] application - Success Async call  :8
[info] application - Success Async call  :9
[info] application - Async finished ************************** :tarun
[info] application - Async started ************************** :tarun1
[info] application - Success Async call  :1
[info] application - Success Async call  :2
[info] application - Success Async call  :3
[info] application - Success Async call  :4
[info] application - Success Async call  :5
[info] application - Success Async call  :6
[info] application - Success Async call  :7
[info] application - Success Async call  :8
[info] application - Success Async call  :9
[info] application - Async finished ************************** :tarun1
这方面的代码是:

package controllers

import play.Logger
import play.api.libs.json.Json
import play.api.mvc._


import scala.concurrent.Future

object StarController extends Controller {
  import play.api.libs.concurrent.Execution.Implicits.defaultContext


  def getStarAsync(name : String) = Action.async{
    val futureResult = Future{
      Logger.info("Async started ************************** :" + name)
      val a = 0;
      for( a <- 1 until 10) {
        Thread.sleep(1000)
        Logger.info("Success Async call  :" + a.toString)
      }
      Logger.info("Async finished ************************** :" + name)
      Map("success" -> Json.toJson(true), "msg" -> Json.toJson("Success Async by :" + name), "code" -> Json.toJson(200))
    }

    futureResult.map{ result =>
      Ok(Json.toJson(result))
    }
  }

}
有谁能帮助我理解,为什么即使使用异步调用,执行也是顺序的?

Action.async不会神奇地使控制器方法异步。唯一不同的是,它期待的是未来的结果,而不是结果。就这样。控制器在其他方面是异步的,因为它们本质上是异步的,也就是说,一个正常的操作无论如何都会被包装在未来。这里的问题是Thread.sleep1000阻塞了它的线程,并且一点也不异步

另一件事是,在开发模式(即activator run)下,play服务器使用单个线程来服务请求,因此它可以正确地处理重新加载/编译、演化等。因此发生的情况是,您只是用同步调用阻塞了该线程。使用activator start应该会看到不同的结果,但即使如此,在这里使用Action.async也没有意义,除非您要将该阻塞委托给不同的线程池


.

只是为了澄清m-z的答案。 这是如何在代码中处理一些异步集合的示例

def getStarAsyncOld(name: String) = Action.async {
  val futureResult = Future {
    Logger.info("Async started ************************** :" + name)
  } flatMap (_ => Future.sequence(for (a <- 1 until 10) yield Future {
    Thread.sleep(1000)
    Logger.info("Success Async call  :" + a.toString)
  })) map { _ =>
    Logger.info("Async finished ************************** :" + name)
    Map("success" -> Json.toJson(true), "msg" -> Json.toJson("Success Async by :" + name), "code" -> Json.toJson(200))
  }

  futureResult.map { result =>
    Ok(Json.toJson(result))
  }
}

我做了很多实验,发现了一件事。也许这听起来很疯狂,但Play仅在同时请求从同一浏览器发送到同一路由时才按顺序处理这些请求。如果我通过curl发出请求,或者从不同的浏览器发出请求,或者甚至从一个浏览器发出请求,但是发送到不同的路由,那么它们将被异步处理。不确定什么样的保护游戏会以这种方式进行,但这种保护是存在的,这是事实。

我也看到过同样的行为。我也无法理解事实。这就是为什么理解异步概念更容易混淆的原因。
def getStarAsync(name: String) = Action.async {
  for {
    _ <- Future(Logger.info("Async started ************************** :" + name))
    _ <- Future.sequence(for (a <- 1 until 10) yield Future {
      Thread.sleep(1000)
      Logger.info("Success Async call  :" + a.toString)
    })
    _ = Logger.info("Async finished ************************** :" + name)
    result = Map("success" -> Json.toJson(true), "msg" -> Json.toJson("Success Async by :" + name), "code" -> Json.toJson(200))
  } yield Ok(Json.toJson(result))
}