Reputation: 9734
In the following code snippet, method bookExists
invokes method find
to determine whether the book identified by the specified id exists:
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
}
}
}
The problem is that the class above doesn't compile probably because I need to wait until the Future
actually completes. I always get the following error message:
[error] /home/j3d/test/BookStore.scala:118: type mismatch;
[error] found : scala.concurrent.Future[Boolean]
[error] required: Boolean
[error] ).map {
[error] ^
What's the correct way to handle this case?
Upvotes: 1
Views: 1523
Reputation: 4182
Unless you are awaiting the result you are mapping this Future[Option[Book]] to another future of type Future[Boolean]. Without the await the computation will take place after the find Future completes (if at all). Change your return type:
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
}
}
}
Upvotes: 2
Reputation: 167921
Normally you'd return Future[Boolean]
and thus defer the requirement to have the answer for as long as possible.
But if it is important to block until the answer is available, then use scala.concurrent.Await
(preferably wrapped in a Try
to catch errors).
Upvotes: 4