cool breeze
cool breeze

Reputation: 4811

How would I handle a Future[User] versus a Future[Option[User]]?

What is the difference in how you handle a Future[User] versus a Future[Option[User]]?

I am also confused as I kind of thought a flatMap removes Options, but is that restricted to them being in a collection?

Upvotes: 0

Views: 94

Answers (2)

Aivean
Aivean

Reputation: 10882

I suggest you to read and understand docs.

In brief, without blocking you can:

  • transform result of the future (using map)
  • combine results of several futures (using flatMap)
  • add completion callback (using onComplete)

You can synchronously wait for future termination using Await to get unwrapped value, but this usually doesn't make much sense (as you are blocking your current thread).

Better add onComplete or onSuccess callback to your future (which will receive unwrapped future's result as parameter):

 val userFuture: Future[Option[User]] = Future { getUserOption() }
 userFuture.onSuccess {
    case userOpt:Option[User] => userOpt.foreach {  user =>
       println(user)  // watch out for thread-safety here!
    }    
 }

Upvotes: 1

wheaties
wheaties

Reputation: 35980

No, flatMap does not remove Option. This is a mistaken but common belief brought upon by the fact that there is an implicit conversion from Option to Traversable that allows you do to things like List(Option(1)).flatMap(x => x) (essentially .flatten.)

Instead, think of flatMap the same way you would do with something more akin to a Monad. Given some type M[_] and a function of type A => M[B] produce a M[B]. So, for flatMap to work for you in this case, you'd have to have a function of type Option[User] => Future[B] for some type B.

def doSomething(ouser: Option[User]): Future[Output] = { ...

val res: Future[Output] = futOptUser.flatMap(doSomething)

Upvotes: 1

Related Questions