我是一个Scala新手:(也就是说,我反对Play framework Action.async和Future calls。
我想在同一个动作中调用2个Futures,并等待它们都计算出来,然后将结果发送到我的视图中。
以下是代码:
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))
}
通过该定义的功能:
def findOne(id: String): Future[Option[PageModel]]
def listTags: Future[List[String]]
我得到这个错误:
[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] ^
我试着用map、for/yield、foreach来处理期权和期货,但总有一个错误仍然存在。
然而,在我添加“标记”功能之前,未来的一个调用运行良好:
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
}
}
}
如何在同一个操作中调用2个Futures并等待它们都计算通过Ok()将它们传递给我的页面浏览量?
非常感谢任何澄清!
可以这样试试。
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
}
}
}
您可以使用< code>Future的< code>flatMap方法。
faceMap
方法采用一个函数,该函数将值映射到一个新的未来g
,然后返回一个在g
完成后完成的未来。
(来自http://docs.scala-lang.org/overviews/core/futures.html)
因此,不妨尝试:
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
}
}
}
您需要映射
和平面映射
未来的以异步访问它们的结果<代码>操作。异步需要一个未来的[结果],因此您必须将未来的映射到该结果。这里有一个简单的方法:
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))
}
}
}
或者您可以使用for理解来清理它,它是平面地图
/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
}
}
}
我还擅自简化了您在< code>findOne结果上的< code >地图。
问题内容: 在Bruce Eckel的“ Thinking In Java,第四版”的第428页(有关类型信息的章节)中,具有以下示例: 也许我有点累,但是我看不到add()方法中对add()的调用是如何工作的。我一直认为它应该有一个引用,或者是一个静态方法(并且我在ArrayList或List中找不到静态add())。我想念什么? 我只是为自己测试,发现这可行: 问题答案: Java为这样的方法
我想在同一框架中使用2个面板。但是button不起作用了?我该怎么做?我想在一个面板上放几个按钮,另一个面板会做一些其他的事情。
我是RxJava的新手,面临以下问题: 我有两个可完成的对象来存储一些数据。我想触发第一个,然后在第一个成功完成后再启动第二个。应该阻止对第二个Completable的调用,直到第一个完成并成功为止。此外,如果第一个完成时出现错误,则还应跳过另一个。 通过查看留档和其他SO问题,或似乎对我有用。但是在手动测试和单元测试中,我可以看到第二个可完成项是与第一个并行触发的:/ 首先完成 第二个可完成 尝
在这个组件中,我在顶部有一个图像,然后在底部有两个其他组件(在内部),它们显示为不同的行。我想把另外两个项目(一个网格和一个图表)放在单行中,我已经尝试过使用flex direction,但它似乎对我不起作用。这可能是因为我已经在父组件中使用了。 ItemsContainer: 我如何修复这一点,使网格出现在左边,图表出现在右边,但在同一行/行? 下面是ItemContainer内部两个主要子组件
UPATE启动 正确答案如下: 是否可以不使用完成块在UIView上执行多个动画 没必要读这个。 上端 我有类似的问题,UIView animateWithDuration会立即返回,但我不能使用完成块,因为我的动画有不同的功能。 但确实想要动画相同的对象。 我在做纸牌游戏,所以我在屏幕上移动纸牌,但在移动之前,我也有一些游戏逻辑。这就是为什么我可以方便地单独制作动画。 如何解决这个问题? @Fo
基本上我有: 错误:只有在显式请求批注处理时才接受类名“test” 非常感谢所有的回复:)