【问题标题】:Usage of Scala Future in Playframework?在 Playframework 中使用 Scala Future?
【发布时间】:2013-08-08 12:25:39
【问题描述】:

在使用 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 函数例如期望 SimpleResult 时,我如何在 Playframework 中使用它们?处理期货的最佳做法是什么?

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

【问题讨论】:

  • 有趣的链接@flavian,谢谢。

标签: scala playframework-2.0


【解决方案1】:

你可以使用Async:

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

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

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

一些关于它的文档here

【讨论】:

  • 你确定吗?据我所知,Async 是一个包装器,期望 Future[SimpleResult]onComplete 返回一个 Unit。使这个不编译。而且我应该补充说我正在使用 Play 2.2.0-M2,它已经通过原生 Scala Futures 切换了 Play 的 Futures。
【解决方案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]

但是,使用例如显式失败的计算可能会更好。 Option(如 Jatin 演示的那样)、Eitherscalaz.\/

编辑:正如您所指出的,PlayPromise 在 Play 2.2 中已弃用。用Future 方法模拟它的行为很简单,例如:

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

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

【讨论】:

  • 确实,在2.2之前的版本中,我使用了.extend1,但是签名与scala.concurrent.Future不兼容。
  • 我已经编辑了我的答案以包括其中一种方法。例如,您还可以创建一个新的Promise,将其放入onComplete 块中,然后返回其Future
猜你喜欢
  • 2018-02-27
  • 2018-02-17
  • 1970-01-01
  • 2014-11-30
  • 1970-01-01
  • 1970-01-01
  • 2023-03-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多