简体   繁体   English

在同一Action.async Scala中调用2个期货

[英]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进行mapflatMap以便异步访问其结果。 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 . 您可以使用FutureflatMap方法。

The flatMap method takes a function that maps the value to a new future g , and then returns a future which is completed once g is completed. flatMap方法采用一个将值映射到新的Future g的函数,然后返回一个一旦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.

相关问题 播放Scala-对Action.async的结果类型感到困惑 - Play scala - confusing about the result type of Action.async Scala播放-Action.async与BodyParser-异常处理 - Scala Play - Action.async with BodyParser - Exception Handling Scala和Play框架2.2.0,Action.async和isAuthenticated - Scala and Play framework 2.2.0, Action.async and isAuthenticated 我可以将Action.async与多个Future一起使用吗? - Can I use Action.async with multiple Futures? Scala Play Action.async无法将Ok解析为mvc.AnyContent - Scala Play Action.async cant resolve Ok as mvc.AnyContent 在Scala Play框架异步动作中组合/链接期货 - Combining/chaining futures in scala play framework async action 播放控制器中Action.async中有条件的Web服务活动的简单配方 - A simple recipe for conditional webservice activity in Action.async in a play controller 在另一个函数中播放Framework Action.async WS - Play Framework Action.async WS within another function 在播放框架中无法在Action.async中找到Writable - Unable to find Writable inside Action.async in play framework Action(parser.json)vs Action.async错误,并且使用并发.Execution.Implicits无法在Play Scala中初始化类控制器 - Action(parser.json) vs Action.async Error, and using concurrent.Execution.Implicits made could not initialize class controllers in Play Scala
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM