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

Convert Future[List[String]] to List[String]

我有以下代码:

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再次请求获取权限?我不这么认为。

关于期货的一般信息

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

一种可能的方法是等待结果,但在产品应用中使用并不好。

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)

游戏与期货

Play 本身可以处理 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)
  }

我在回答标题中的问题

以明智的方式(并且无需访问 time-machine)实现功能 Future[A] => A 的方法是等待完成未来,因为值 Future[A] 表示类型 A 的值将在未来产生。

检查您的图书馆以找到正确的等待方法。 对于 Scala std lib,它是 .result 正如 Jean 评论的那样,Scala std lib 的正确方法是使用 Await.result()

注意等待是一个阻塞方法调用。如果您想避免这种情况(并且有一些很好的理由这样做),您应该查看安德烈亚斯的回答。