2014-06-19 2 views
0

Dans l'extrait de code suivant, la méthode bookExists invoque la méthode find pour déterminer si le livre identifié par l'identifiant indiqué existe:Scala: Comment attendre un avenir

class BookStore { 

    def find(id: String): Future[Option[Book]] = { 
    // read from db 
    ... 
    } 

    def bookExists(id: String): Boolean = { 
    find(id).map { 
     case Some(_) => true 
     case _ => false 
    }.recover { 
     case e => false 
    } 
    } 
} 

Le problème est que la classe ci-dessus n » t compiler probablement parce que j'ai besoin d'attendre jusqu'à ce que le Future se termine réellement. Je reçois toujours le message d'erreur suivant:

[error] /home/j3d/test/BookStore.scala:118: type mismatch; 
[error] found : scala.concurrent.Future[Boolean] 
[error] required: Boolean 
[error]  ).map { 
[error]    ^

Quelle est la bonne façon de gérer ce cas?

+2

Pourquoi pas '.map (_. NonEmpty)'? –

Répondre

2

Si vous n'attendez pas le résultat, vous mappez ce Futur [Option [Livre]] à un autre futur de type Futur [Booléen]. Sans l'attente, le calcul aura lieu après la conclusion de l'avenir se termine (le cas échéant). Changez votre type de retour:

def bookExists(id: String): Future[Boolean] = { 
    find(id).map { _ match { // '_' in the map is a Option[Book] extracted from the Future[Option[Book]] find returns 
     case Some(_) => true // '_' in the match is Book extracted from the Option[Book] in the match statement 
     case _ => false 
     }.recover { 
     case e => false 
     } 
    } 
    } 
2

Normalement, vous renverrez Future[Boolean] et ainsi différer l'exigence d'avoir la réponse le plus longtemps possible.

Mais s'il est important de bloquer jusqu'à ce que la réponse soit disponible, alors utilisez scala.concurrent.Await (de préférence enveloppé dans un Try pour détecter les erreurs).