2017-01-31 6 views
0

私は、Slickを使用してデータベースからデータを取得するasync Play Actionを持っています。そしてスリック、明らかに、ブロックを回避するためにFuture Sを使用しています。単一のプレイアクション内で独立したSlickクエリを作成する

def show(id: Long) = Action.async { 
db.run(entities.filter(_.id === id).result.headOption).map { 
    case None => templateFor("NEW_OBJECT") 
    case Some(x) => Ok(x) 
} 
def templateFor(code: String): Future[Result] = { 
    db.run(templates.filter(_.code === code).result.headOption).map { 
    case None => InternalServerError("No template") 
    case Some(x) => Ok(x) 
    } 
} 

問題がtemplateFor()戻りFuture、そのプレイが期待するものではありません全体Action戻りFuture[Future[Result]]への呼び出しです。だから、私はそれを取り除きたいですFuture入れ子。それを行う簡単な方法は完了のためAwaitですが、私は不要なブロックを避けたいと思います。 templateFor()によって生成されたFuture[Result]をそのまま私のActionから返すことができれば、それは外側Futureをそれに置き換えるといいですね。

+1

は 'それをflatMap' :) – ipoteka

+2

を@ipotekaが言ったように:https://cdn.meme.am/cache/instances/folder331/500x/67321331.jpg :) –

答えて

2

あなたはこのようなFuture[T]などの任意monandic strutctureのためにそのためのflatMap

を使用することができ、flatMapは、モナドとは、あなたにFuture[K]を与えるためにそれらを平坦化する場合は、すべての要素にその関数を適用し、タイプT => SomeOtherMonad[K]の機能を取ります。

def show(id: Long) = Action.async { 
    db.run(entities.filter(_.id === id).result.headOption).flatMap { 
    case None => templateFor("NEW_OBJECT") 
    case Some(x) => Future(Ok(x)) 
    } 

    def templateFor(code: String): Future[Result] = 
    db.run(templates.filter(_.code === code).result.headOption).map { 
     case None => InternalServerError("No template") 
     case Some(x) => Ok(x) 
    } 
} 
関連する問題