用于理解Future [Option [T]]并根据条件执行后续期货

时间:2015-08-27 22:11:28

标签: scala playframework

你如何使用进行理解,期货返回期权,即Future [Option [T]],并且当且仅当满足条件时执行后续期货,例如例如,仅当第一个未来在给定字段上具有非空值时才应执行第二个未来?

我不确定自己是否能够很好地解释自己想要实现的目标,但这里有一些代码对我不起作用:

def show(id: Int, slug: String) = Action.async { implicit request =>
  for {
    aWithbTuple <- someDAO.findByIDJoined(id)
    cID = aWithbTuple.map(_._1.cID).get if aWithbTuple.isDefined
    c <- cDAO.findByID(cID) //Load the c table record only if the cID field is present in the first member of the tuple of aWithbTuple
  } yield {
    aWithbTuple.fold(NotFound) { case (a, b) =>
      Ok(views.html.show(a, b, c))
    }
  }
}

它汇编得很好,但如果第一个未来的结果是,我会得到一个例外,我想要得到的是结果,如果第一个未来返回,但似乎即使第一个未来返回,第二个未来仍然会被执行,因此我得到一个例外。< / p>

1 个答案:

答案 0 :(得分:3)

您遇到的问题是 for-comprehension 中的if不是 postfix条件,您可能会在其他语言中找到它。相反,它是过滤器操作。

不同之处在于,作为后缀条件,如果条件失败,它将阻止在其之前执行的操作。但是,作为过滤器,执行操作然后使用过滤器来确定是否继续。因此,当aWithbTuple.map(_._1.cID).get选项为getNone引发if时,您someDAO.findByIDJoined(id)失败。

如果您使用aWithbTuple作为未来None的过滤器,则会在{{1} get时将 for-comprehension 与未来失败进行短路}是def show(id: Int, slug: String) = Action.async { implicit request => for { aWithbTuple <- someDAO.findByIDJoined(id) if aWithbTuple.isDefined cID = aWithbTuple.map(_._1.cID).get c <- cDAO.findByID(cID) //Load the c table record only if the cID field is present in the first member of the tuple of aWithbTuple } yield { aWithbTuple.fold(NotFound) { case (a, b) => Ok(views.html.show(a, b, c)) } } } ,因此您可以安全地拨打example.com/folder/index.php/pagename

example.com/pagename