2015-12-04 5 views
3

У меня есть следующий код:Преобразовать Future [List [String]] в список [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) 
    } 
} 

Я просто хочу, чтобы получить пользователь, а затем заполнить все разрешения. Индивидуальные разрешения и разрешения, унаследованные ролью, назначенной пользователю.

Лучше ли получить пользователя, а затем выполнить другой запрос, чтобы получить разрешения на основе идентификатора пользователя? Я так не думаю.

+1

Несмотря на то, что никогда не работал с «Будущим», я ожидаю, что единственный способ получить ценность из «Будущего» - это ждать, что означает вызов «результата» для класса STD-lib 'Future'. Это смысл «Будущего», нет? – ziggystar

+2

Пожалуйста, поставьте контекст. В * Play! * Вам, вероятно, следует всегда избегать «Await'ing», поэтому, я полагаю, вы должны адаптировать окружающий код для работы с 'Future' – Odomontois

ответ

6

Общая информация по фьючерсам

Вы найдете всю информацию о Futures вам нужно на 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) 

Play и Futures

сама Игра может обрабатывать 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) 
    } 
+0

Но я хочу сохранить результат в переменной, не возвращая ее через действие – glarkou

+0

Это больше похоже на комментарий, чем на фактический ответ – Odomontois

+3

Это ответ. Но ОП, скорее всего, задает неправильный вопрос. –

2

Я отвечаю на вопрос в названии.

только способ реализации функции Future[A] => A в разумном пути (и без доступа к машине времени) должны ожидать завершения будущего, так как значение Future[A] указует на значение типа A будет давать в будущее.

Проверьте правильность использования своей библиотеки. Для Scala std lib это .result. Как комментирует Жан, правильным способом для Scala std lib является использование Await.result().

Обратите внимание, что ожидание является блокировка метод call. Если вы хотите избежать этого (и для этого есть веские причины), вы должны проверить ответ Андреаса.

+3

Как указано в документации scala, правильный способ блокировки и получения значения из 'scala.concurrent.Future' заключается в использовании' Await .result() '. См. «Этот метод не следует вызывать напрямую; вместо этого используйте Await.result. 'в http://www.scala-lang.org/api/current/index.html#[email protected]:scala.concurrent.duration.Duration)(implicitpermit:scala .concurrent.CanAwait): Т – Jean