我的play-framework API服务器出了问题。我需要在后台运行一些处理,返回带有结果的Future
,然后将结果写为响应。但是,请求线程全部输出并在我的Future完成之前返回。这是代码......
def requestAction(): Action[AnyContent] = Action.async { implicit request =>
var fResult: Future[String] = Future { "initial value" }
try {
fResult = doSomethingAsyncAndGetResponseString(); // return "great, everything is done"
}
catch {
case t: Throwable {
fResult = Future { "failed" }
}
}
// done, return response, but the problem is, this is executed first because doSomethingAsyncAndGetResponseString() is still executing and returns later
fResult.map( res => {
// problem here, because I get "initial value" which is not what I want
Ok(res)
}
}
有没有办法在没有Async.await
的情况下获得“伟大,一切都已完成”或“失败”?我一直在我的API服务器中使用这种格式,但今天它已经崩溃了,因为在我编写的新API中,doSomethingAsyncAndGetResponseString
有点长。我没想到,所以我对结构的理解一定是错的。
提前致谢!
答案 0 :(得分:3)
您正尝试使用Java
编写Scala
代码。
你做错了。阅读Future
以及如何使用它们。
以下是tutorial
Future
可以使用map
和flatMap
构造进行组合。 recover
和recoverWith
将授予用户访问计算管道中发生的异常的权限
你必须做这样的事情,如下所示
def requestAction(): Action[AnyContent] = Action.async { implicit request =>
Future { "initial value" }.flatMap { _ =>
doSomethingAsyncAndGetResponseString() // returns Future
}.map { res =>
Ok(res)
}.recover { case th =>
Ok(th.getMessage)
}
}
异常处理内置于Future
。
recover
可以访问异常,还可以帮助用户在异常情况下提供替代成功值。
recoverWith
可以访问异常,还可以帮助用户提供/链接可能成功或失败的替代Future
计算。
Future {
throw new Exception("foo exception")
}.recover {
case th => println(s"msg: ${th.getMessage}")
}