我在Play动作中遇到问题,我的视图页面需要一个ApiResponse对象,但我是一个未来[ApiResponse]并且似乎无法解开"打开"未来。
def confirm(token: String) = Action async { request =>
// loadTokenInfo returns Future[Option[SP]]
loadTokenInfo(token).map { maybeSP =>
maybeSP match {
case Some(sp) =>
val someConfig = SomeConfiguration(..)
// confirmSubscription returns Future[ApiResponse]
for {
apiResp <- apiService.confirmSubscription(sp.account, sp.website, sp.list, sp.listMember)
} yield Ok(views.html.subscription.confirm(ConfirmPageViewModel(someConfig, sp, apiResp)))
case _ =>
Ok(views.html.errorpage.empty(PageNotFound("asdf")))
}
}
}
我收到错误:
发现[错误]:scala.concurrent.Future [play.api.mvc.Result] [错误]要求:play.api.mvc.Result
我也试图映射apiResp,但那不起作用:
apiResp.map { r =>
Ok(views.html.subscription.confirm(ConfirmPageViewModel(pageConfig, sp, r)))
}
我是否必须在此致电Await.result?我不想明显阻止,但不知道此时该怎么做。
答案 0 :(得分:2)
我猜是因为您没有指定错误发生的位置以及confirmSubscription
返回的内容 - 大概是某个Future
。
但我可以说至少你需要在默认情况下返回:
Future.successful(Ok(views.html.errorpage.empty(PageNotFound("asdf"))))
为了对世界上所有人的爱,不要使用Await.result
。
一些随机的,无关的笔记:
map
和getOrElse
比Option
上的模式匹配更加惯用。confirmSubscription
刚刚使用sp
实例并让apiService
决定如何使用它,那就太好了。 Future
而非使用for
理解 - 正如您已经做过的那样 - 只有一个。