将Future [List [String]]转换为List [String]

时间:2015-12-04 13:12:22

标签: scala playframework-2.0

我有以下代码:

Some(db.run(unionPermissionQuery.result).map(_.map(_.name).toList))

我收到以下错误:

[error]  found   : scala.concurrent.Future[List[String]]
[error]  required: List[String]
[error]           Some(db.run(unionPermissionQuery.result).map(_.map(_.name).toList)),
[error]                                                       ^
[error] one error found

所以我想我必须将Future[List[String]]转换为List[String]。我是scala的新手,如果这太容易了,我很抱歉。

完整代码:

  def find(loginInfo: LoginInfo): Future[Option[models.admin.User]] = {
val userQuery = for {
  dbLoginInfo <- loginInfoQuery(loginInfo)
  dbUserLoginInfo <- Userlogininfo.filter(_.logininfoid === dbLoginInfo.id)
  dbUser <- User.filter(_.userid === dbUserLoginInfo.userid)
} yield dbUser

db.run(userQuery.result.headOption).map { dbUserOption =>
  dbUserOption.map { user =>
    val permissionQuery = for {
      dbUserPermission <- Userpermission.filter(_.userid === user.userid)
      dbPermission <- Permission.filter(_.id === dbUserPermission.permissionid)
    } yield dbPermission

    val rolePermissionQuery = for {
      dbUserRole <- Userrole.filter(_.userid === user.userid)
      dbRole <- Role.filter(_.id === dbUserRole.roleid)
      dbRolePermission <- Rolepermission.filter(_.roleid === dbRole.id)
      dbPermission <- Permission.filter(_.id === dbRolePermission.permissionid)
    } yield dbPermission

    val unionPermissionQuery = permissionQuery union rolePermissionQuery

    models.admin.User(
      UUID.fromString(user.userid),
      user.firstname,
      user.lastname,
      user.jobtitle,
      loginInfo,
      user.email,
      user.emailconfirmed,
      Some(db.run(unionPermissionQuery.result).map(_.map(_.name).toList)),
      user.enabled)
  }
}

我只想获取用户,然后填写所有权限。分配给用户的角色继承的个人权限和权限。

获取用户然后执行另一个请求以获取基于用户ID的权限是否更好?我不这么认为。

2 个答案:

答案 0 :(得分:6)

关于期货的一般信息

您可以找到所需的期货的所有信息 http://docs.scala-lang.org/overviews/core/futures.html

可能的方法是等待结果,但在prod应用程序中使用它并不好。

val myFutureResult : Future[T] = Future {...}
val myResult : T = Await.result(myFutureResult, secondsToWait seconds)

通常情况下,不是等待结果并将其存储在变量中,您可以map构建它,并在最后一刻仅使用Await。

val myFutureResult : Future[T] = Future {...}
def myFunctionOnT(in: T) = ...

for {res <- myFutureResult } yield myFunctionOnT(res)

游戏和期货

默认情况下,播放本身可以使用Future[T]代替Action.async {}来处理Action{},您可以在此处找到更多内容:https://www.playframework.com/documentation/2.5.x/ScalaAsync

此信息适用于扩展问题

db.run(unionPermissionQuery.result).map(_.map(_.name).toList).map { permission =>

models.admin.User(
  UUID.fromString(user.userid),
  user.firstname,
  user.lastname,
  user.jobtitle,
  loginInfo,
  user.email,
  user.emailconfirmed,
  Some(permission),
  user.enabled)
  }

答案 1 :(得分:2)

我正在回答标题中的问题。

以合理的方式(并且无法访问时间机器)实现函数Future[A] => A唯一方式是等待未来的完成,作为值{{ 1}}表示类型Future[A]将来会产生的值。

检查您的磁带库是否有正确的等待方法。 对于Scala std lib,它是A正如Jean评论的那样,Scala std lib的正确方法是使用.result

请注意,等待是阻止方法调用。如果你想避免这种情况(并且有充分的理由这样做),你应该查看Andreas的回答。