konquestor
konquestor

Reputation: 1308

Scala Futures: Returning a future with empty map leaves the Future uncompleted

If my method is returning Future of Map, like below

 def getFutureMap(count:Int):Future[Map[Int, String]] = {

     Future {
         val m: scala.collection.mutable.Map[Int, String] = scala.collection.mutable.Map[Int, String]()
         for (i <- 1 to count) {
            m.put(i, s"$i")
          }
         m.toMap
     }
 }

Why does it say that Future is not completed?

scala> getFutureMap(0).map { print}
Map()res6: scala.concurrent.Future[Unit] = Future(<not completed>)

Upvotes: 0

Views: 2172

Answers (1)

prayagupadhyay
prayagupadhyay

Reputation: 31222

When I tried mapping on future response I get in scala REPL 2.11.7 is,

scala> import scala.concurrent.Future
import scala.concurrent.Future

scala> import scala.concurrent.ExecutionContext
import scala.concurrent.ExecutionContext

scala> import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.ExecutionContext.Implicits.global

scala> getFutureMap(0).map { print}
Map()res7: scala.concurrent.Future[Unit] = scala.concurrent.impl.Promise$DefaultPromise@3f92a84e

scala> getFutureMap(100).map { print}
res8: scala.concurrent.Future[Unit] = scala.concurrent.impl.Promise$DefaultPromise@574cd322
Map(69 -> 69, 88 -> 88, 5 -> 5, 10 -> 10, 56 -> 56, 42 -> 42, 24 -> 24, 37 -> 37, 25 -> 25, 52 -> 52, 14 -> 14, 20 -> 20, 46 -> 46, 93 -> 93, 57 -> 57, 78 -> 78, 29 -> 29, 84 -> 84, 61 -> 61, 89 -> 89, 1 -> 1, 74 -> 74, 6 -> 6, 60 -> 60, 85 -> 85, 28 -> 28, 38 -> 38, 70 -> 70, 21 -> 21, 33 -> 33, 92 -> 92, 65 -> 65, 97 -> 97, 9 -> 9, 53 -> 53, 77 -> 77, 96 -> 96, 13 -> 13, 41 -> 41, 73 -> 73, 2 -> 2, 32 -> 32, 34 -> 34, 45 -> 45, 64 -> 64, 17 -> 17, 22 -> 22, 44 -> 44, 59 -> 59, 27 -> 27, 71 -> 71, 12 -> 12, 54 -> 54, 49 -> 49, 86 -> 86, 81 -> 81, 76 -> 76, 7 -> 7, 39 -> 39, 98 -> 98, 91 -> 91, 66 -> 66, 3 -> 3, 80 -> 80, 35 -> 35, 48 -> 48, 63 -> 63, 18 -> 18, 95 -> 95, 50 -> 50, 67 -> 67, 16 -> 16, 31 -> 31, 11 -> 11, 72 -> 72, 43 -> 43, 99 -> 99, 87 -> 87, 40 -> 40, 26 -> 26, 55 -> 55, 23 -> 23, 8 -> 8, 75 -> 75, 58 -> 58, 82 -> 82, 36 -> 36, 30 -> 30, 51 -> 51, 19 -> 19, 4 -> 4, 79 -> 79, 94 -> 94, 47 -> 47, 15 -> 15, 68 -> 68, 62 -> 62, 90 -> 90, 83 -> 83, 100 -> 100)

The key here is when do map/ or foreach on future its still async and your code execution moves forward.

If you want to wait until the future is completed, use onComplete with partial function.

So, in your case it would be as below,

scala> import scala.util.Success
import scala.util.Success

scala> import scala.util.Failure
import scala.util.Failure

scala> getFutureMap(0).onComplete {
     | case Success(x) => println(x)
     |  case Failure(y) => println(y)
     | }
Map()

and,

scala>  getFutureMap(5).onComplete {
     |    case Success(x) => println(x)
     |    case Failure(y) => println(y)
     |  }
Map(5 -> 5, 1 -> 1, 2 -> 2, 3 -> 3, 4 -> 4)

Upvotes: 2

Related Questions