除了 Play Framework 中的可读性之外,还有其他使用 Action.async 的理由吗?

Are there any reasons to use Action.async other than readability in Play Framework?

我阅读了播放异步操作的 official doc 并理解 Action.async 是

just a facility to simplify creating actions based on APIs that return a Future.

我担心的是,如果您盲目地 return Future[Response],似乎会引入未处理的错误,因为 Future 可能会失败。

当然,您可以通过类似

的方式处理失败案例
def index = Action.async {
  intensiveComputation()
    .map { i => Ok("Got result: " + i) }
    .recover { case e: Exception => InternalServerError("error")}
}

但您也可以通过编写类似这样的内容来使用 Action,并通过在 Action.async 上始终如一地使用 Action,您不会忘记处理错误情况。

def index = Action {
  intensiveComputation().onComplete {
    case Success(i) => Ok("Got result: " + i)
    case Failure(e) => InternalServerError("error")
  }
}

所以如果我不想引入意外错误,总是使用 Action.apply 是个好习惯吗?还是我遗漏了什么?

一个高水平的回答:

第二种方法甚至不会编译,根据我的理解,onComplete return 类型是 Unit 和 Play 动作期望 Request[AnyContent] => 结果(在 Action 的情况下)或 Request[AnyContent] =>未来[结果](在 Action.async 的情况下)。

希望对您有所帮助。

不用担心,Play 提供了很好的错误处理

本质上有一个错误处理程序,它将异常包装在相应的 HTTP 异常中。例如,未处理的错误将是 HTTP 500 异常。

您也可以提供自己的错误处理程序。

有关详细信息,请参阅 Play Documentation