6

在使用 Playframework 时,我有时会遇到这种情况:

def myFunction:Future[String] = {
    // Do some stuff
}

myFunction.onComplete {
    case Success(myString) => // Du Stuff
    case Failure(error) => // Error handling
}

但正如 Scala 文档中所述,Future.onComplete返回一个 Unit。Action当函数例如期望 a时,如何在 Playframework 中使用它们SimpleResult?处理期货的最佳实践是什么?

编辑:我应该补充一点,我正在使用 Play-2.2.x 分支,它已经将 Play Future 换成了 Scala Future。

4

2 回答 2

8

您可以使用Async

def index = Action{
    val myFunction:Future[Option[String]] = //
    Async{
      myFunction.map{
        case Some(x) => Ok(x)
        case None => InternalServerError
      }
    }
}

基本上你告诉play:每当myFunction被评估时,将结果返回给用户。这里的技巧是mapFuture内容而不是使用回调,这使您可以对结果进行操作。

美妙的部分是它仍然是异步的。从某种意义上说,http请求线程评估索引不会被阻塞。

这里有一些关于它的文档。

于 2013-08-06T11:58:01.813 回答
2

Play(至少在 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]

然而,使用 eg Option(如 Jatin 演示的那样)Either、 或使计算显式失败可能会更好scalaz.\/

编辑:正如您所指出的,PlayPromise在 Play 2.2 中已弃用。用方法来模拟它的行为是微不足道的Future,例如:

myFunction.map(v => s"Got result string: $v").recover {
  case t => s"Got throwable: ${t.getMessage}"
}

如果您想重新创建extend1语法,添加适当的隐式将很简单。

于 2013-08-07T02:45:50.870 回答