[英]Call 2 Futures in the same Action.async Scala Play
I'm a newby in Scala :( That's said, I'm fighting against Play framework Action.async and Future calls. 我是Scala的newby :(就是说,我正在与Play框架Action.async和Future调用作斗争。
I'd like to call 2 Futures in the same Action and wait until they both compute to send their result in my view. 我想在同一操作中调用2个期货,并等到它们都计算出结果后再发送给我。
Here is the code : 这是代码:
def showPageWithTags(category: String) = Action.async {
val page = PageDAO.findOne(Json.obj("category" -> category)).map {
case Some(page) => {
page.content = page.content.byteArrayToString
}
}
val futureTags = ArticleDAO.listTags
Ok(views.html.web.pages.show(page, futureTags))
}
with this defined functions : 具有定义的功能:
def findOne(id: String): Future[Option[PageModel]]
def listTags: Future[List[String]]
I get this errors : 我得到这个错误:
[error] found : Some[A]
[error] required: models.PageModel
[error] case Some(page) => {
[error] ^
.../...
[error] found : None.type
[error] required: models.PageModel
[error] case None => {
[error] ^
.../...
[error] found : Option[Nothing]
[error] required: scala.concurrent.Future[play.api.mvc.Result]
[error] optionPage.map {
[error] ^
.../...
[error] found : scala.concurrent.Future[Unit]
[error] required: models.PageModel
[error] Ok(views.html.web.pages.show(optionPage, futureTags))
[error] ^
.../...
[error] found : scala.concurrent.Future[List[String]]
[error] required: List[String]
[error] Ok(views.html.web.pages.show(optionPage, futureTags))
[error] ^
I've tried map, for/yield, foreach to deal with Option and Future but there is always one of this errors which remains. 我已经尝试过map,for / yield,foreach来处理Option和Future,但始终存在这种错误之一。
Yet the one Future call was working good before I add the "Tag" functionality : 但是,在我添加“标记”功能之前,一个Future呼叫运行良好:
def showPage(category: String) = Action.async {
PageDAO.findOne(Json.obj("category" -> category)).map {
case Some(page) => {
page.content = page.content.byteArrayToString
Ok(views.html.web.pages.show(page))
}
case None => {
NotFound
}
}
}
How can I call 2 Futures in the same action and wait until they both compute to pass them to my page view via Ok() ? 如何在同一操作中调用2个期货并等待它们都计算出通过Ok()将它们传递到我的页面视图中?
Many thanks to any clarifications ! 非常感谢任何澄清!
You need to map
and flatMap
the Future
s in order to access their results asynchronously. 您需要对
Future
进行map
和flatMap
以便异步访问其结果。 Action.async
expects a Future[Result]
, so you must map your Future
s to that. Action.async
需要Future[Result]
,因此您必须将Future
映射到该对象。 Here's a simple way: 这是一个简单的方法:
def showPageWithTags(category: String) = Action.async {
val page = PageDAO.findOne(Json.obj("category" -> category)).map {
case Some(page) => {
page.content.byteArrayToString
}
}
val futureTags = ArticleDAO.listTags
page.flatMap { page =>
futureTags.map { tags =>
Ok(views.html.web.pages.show(page, tags))
}
}
}
Or you can clean this up using a for-comprehension, which is syntactic sugar for flatMap
/ map
. 或者,您可以使用for-
flatMap
进行整理,这是flatMap
/ map
语法糖。
def showPageWithTags(category: String) = Action.async {
for {
pageOpt <- PageDAO.findOne(Json.obj("category" -> category))
.map(_.map(_.content.byteArrayToString))
tags <- ArticleDAO.listTags
} yield {
pageOpt.map { page =>
Ok(views.html.web.pages.show(page, tags))
} getOrElse {
NotFound
}
}
}
I also took the liberty of simplifying your map
on the findOne
results. 我还自由地简化了
findOne
结果上的map
。
You can use the flatMap
method of the Future
. 您可以使用
Future
的flatMap
方法。
The
flatMap
method takes a function that maps the value to a new futureg
, and then returns a future which is completed onceg
is completed.flatMap
方法采用一个将值映射到新的Futureg
的函数,然后返回一个一旦g
完成就完成的Future。
(from http://docs.scala-lang.org/overviews/core/futures.html ) (来自http://docs.scala-lang.org/overviews/core/futures.html )
So maybe try: 所以也许尝试:
def showPage(category: String) = Action.async {
ArticleDAO.listTags.flatMap { tags =>
PageDAO.findOne(Json.obj("category" -> category)).map {
case Some(page) => {
page.content = page.content.byteArrayToString
Ok(views.html.web.pages.show(page, tags))
}
case None => {
NotFound
}
}
}
You can try like this. 您可以这样尝试。
def showPageWithTags(category: String) = Action.async {
for{
pOpt <- PageDAO.findOne(Json.obj("category" -> category))
futureTags <- ArticleDAO.listTags
} yield{
pOpt match {
case Some(x)=> Ok(views.html.web.pages.show(x.content.byteArrayToString, futureTags))
case _=> NotFound
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.