这个 Play for Scala 方法(应该返回Future[play.api.mvc.Result]
)调用另一个方法run
这是一个可能引发异常的未来。如果run
没有引发异常,则该方法应返回一个ret
等于0
的 Json。 如果run
确实抛出异常,则该方法应重新调整 Json,ret
等于1
。
问题是OnComplete
抛出编译错误:
类型不匹配;找到 : 所需单位: scala.concurrent.Future[play.api.mvc.Result]
如何解决这个问题?
def test (req:Int) : Future[play.api.mvc.Result] = {
val future = run(req)
future.map {
result =>
val json = JsObject(Seq(
"rs" -> Json.toJson(result),
"ret" -> JsString("0")
))
Ok(json)
}
future.onComplete { // <-- compilation error
case Success(_) => // do nothing
case Failure(ex) => {
val json = JsObject(Seq(
"msg" -> JsString(ex.getMessage),
"ret" -> JsString("1")
))
Ok(json)
}
}
}
在 Scala 中,方法中最后一个表达式的结果成为该方法的返回值。future.onComplete
返回一个单位,这使得函数体"返回"一个单位。
你真正想要的是recover
def test (req:Int) : Future[play.api.mvc.Result] = {
run(req)
.map(result => Ok(JsObject("rs" -> ..., "ret" -> 0)))
.recover({ case NonFatal(ex) =>
Ok(JsObject(Seq("msg" -> ..., "ret" -> 1))
})
}
另外,请注意,map
返回新的 future,因此在您的示例中,您将onComplete
回调附加到run
返回的未来,其中不包括该 json 处理;因此onComplete
Failure(ex)
分支不会捕获map
调用中的失败。如您所见,我已经在上面的代码片段中纠正了这一点。