I am curious about how it is possible to return a future that contains a string value that is calculated in a separate thread and doesn't block the calling thread.

I have tried using a Runnable and passing it into a thread pool, but the overridden "run" method cannot return anything for the future, so that didn't work. I feel like I should be returning a future within my main future that gives back the string when it is done creating it, but I am not sure how. I want the outside future to immediately return.

def find(): Future[String] = {
    Future {
        val f = Future {
           getString() // This future gets the string and doesn't block the outside future from immediately returning

        val s = Await.result(f, Duration.Inf)

How could I get the inner future to calculate a value without blocking the outer future from immediately returning? Thanks!

1 Answers

gandaliter On

Your simplified code is a little confusing, but I'm guessing that what you really want to do is flatten a Future[Future[String]] to a Future[String]. If you can avoid creating the outer future in the first place (which your code would suggest) then you don't need to do this - just return a Future[String] without awaiting it, and you won't block a thread.

If you want to flatten the Future[Future[String]] then there are a few explanations here. In short, if you're in Scala 2.12+, you can just call f.flatten. Before that, use f.flatMap(identity) (where f is your Future[Future[String]]).

If you're writing Await.result anywhere except the outermost point in your code, you're probably doing it wrong: lookup how to use map and flatMap, and for comprehensions (which make chains of map and flatMap look a little neater).