你如何使用进行理解,期货返回期权,即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>
答案 0 :(得分:3)
您遇到的问题是 for-comprehension 中的if
不是 postfix条件,您可能会在其他语言中找到它。相反,它是过滤器操作。
不同之处在于,作为后缀条件,如果条件失败,它将阻止在其之前执行的操作。但是,作为过滤器,执行操作然后使用过滤器来确定是否继续。因此,当aWithbTuple.map(_._1.cID).get
选项为get
时None
引发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