How does a for .. Yield strip out a Future?

283 views Asked by At

I am struggling to understand how this code 'strips out' the Future.

getFutureResult() returns a Future[String]. So how come the return from the yield is only a String?

def getFutureResult:Future[String] = { ... }

def getMyResult:String = {

   for {
     myFutureResult <- getFutureResult()
   } yield {
     myFutureResult
   }

}
1

There are 1 answers

4
axel22 On

It is translated according to Scala for-comprehension translation rules:

for (x <- <expr>) yield f(x)

becomes:

<expr>.map(x => f(x))

This is a desugaring done by the compiler irregardless if <expr> has the type of a collection, a future or something else. Future in Scala has a method map, so it uses the myFutureResult String from above to construct another Future[String].

You never know if the resulting future getMyResult is completed -- you should install an onComplete callback that will be called by the resulting future once it completes:

getMyResult onComplete {
  case Success(x) => println("Yes! " + x)
  case Failure(t) => println("An error: " + t)
}

The code for the onComplete method is executed asynchronously -- it might happen on a different thread, much later or simultaneously.

If you really need to know if the Future has completed, use the:

Await(getMyResult, 0 nanos)

pattern to block the calling thread until the getMyResult future is completed. In general, you should avoid this and compose your Future code using for-comprehensions and callback.