使用Playframework时,我有时会遇到这种情况:
def myFunction:Future[String] = {
// Do some stuff
}
myFunction.onComplete {
case Success(myString) => // Du Stuff
case Failure(error) => // Error handling
}
但正如Scala文档中所述,Future.onComplete
返回一个单元。
如果Action
函数例如期望SimpleResult
,我如何在Playframework中使用它们?处理期货的最佳做法是什么?
答案 0 :(得分:7)
您可以使用Async
:
def index = Action{
val myFunction:Future[Option[String]] = //
Async{
myFunction.map{
case Some(x) => Ok(x)
case None => InternalServerError
}
}
}
基本上你告诉玩法:每当评估myFunction
时,将结果返回给用户。这里的诀窍是在map
内容上Future
而不是使用回调,这使您可以对结果进行操作。
很棒的部分是它仍然是异步的。从某种意义上说,http请求线程评估索引不会被阻止。
关于它的一些文档here。
答案 1 :(得分:1)
播放(至少在2.1中)添加了一个您可能会觉得有用的extend1
方法:
def myFunction: Future[String] = ???
myFunction.extend1 {
case Redeemed(v) => s"Got result string: $v"
case Thrown(t) => s"Got throwable: ${t.getMessage}"
} // : Future[String]
然而,使用例如明确失败的计算可能更好。 Option
(正如Jatin所示),Either
或scalaz.\/
。
修改:正如您所指出的,在Play 2.2中不推荐使用PlayPromise
。使用Future
方法模拟其行为是微不足道的,例如:
myFunction.map(v => s"Got result string: $v").recover {
case t => s"Got throwable: ${t.getMessage}"
}
如果您想重新创建extend1
语法,添加适当的含义会很简单。