由于我第一次使用Play 2进行开发,我发现我在控制器中做了很多这样的事情(一个更简单的例子):
val promUser = Akka.future(UserService.findByUsername(access.username))
Async(
promUser.map {
_.map{
user => {
val promService = Akka.future(ServiceService loadOnlyWithUser (id,user.id.get))
Async(
promService.map { _.map { service =>
Ok(toJson(service))
}.getOrElse(BadRequest("not accessible"))}
)
}
}.getOrElse {
BadRequest("unauthorised")
}
}
)
拥有单一的未来会更好吗?例如:
val promService = Akka.future{
val userOption = UserService.findByUsername(access.username)
userOption.map( user => {
ServiceService loadOnlyWithDeveloper (id,user.id.get)
}).getOrElse(None)
}
Async(
promService.map { _.map { service =>
Ok(toJson(service))
}.getOrElse(BadRequest("unauthorised"))}
)
我一方面考虑到控制器的许多期货/回报可能会增加开销,在一个未来的组中,对一个未来的调用将更具可读性,但会导致在Akka系统中运行更大的“线程”。对于更大的工作,我有一个额外的Akka系统,所以这些只包含最多4个SQL事务。至于我可以从apache工作台上解决,上面的例子之间没有任何区别......我有什么遗漏吗?
答案 0 :(得分:3)
与您的示例相比,性能没有任何差异,因为它们是等效的。
当你写:
val promUser = Akka.future(UserService.findByUsername(access.username))
它不会开始评估Future
,它只会在您映射它时执行。
据我了解,你需要考虑期货构成。这是一个非常好的文档,我建议:http://docs.scala-lang.org/sips/pending/futures-promises.html
如果您需要按顺序执行一系列查询,那么如果您有多个Futures,每个数据库访问一个,我认为它不会产生影响。例如。检索记录,然后将其删除。
你可以利用Futures(除了让你的应用程序无阻塞之外)是利用for-comprehension语法,这样你就可以同时运行两个或更多个异步Futures,例如
for {
authUser <- User.findById(request.authUserId)
otherUser <- User.findById(id)
} yield (authUser, otherUser)
另外,我建议您使用flatMap
一起撰写期货,而不是使用多个Async{}
块。这样,您就可以有效地将多个期货Future[Future[Result]]
展平为一个可以AsyncResult
的单一期货。