The last page dealt with fixed numbers of futures. In the real world, we often have to work with unknown quantities.
Once again using the temperature
method defined before, we’ll create
a higher-level method to work with its future values. First, we can
work with Scala collections in familiar ways.
val locs = List(Location("New York", "NY"),
Location("Los Angeles", "CA"),
Location("Chicago", "IL"))
val temps =
for(loc <- locs)
yield for (t <- temperature(loc))
yield (t -> loc)
Now we have a list of future city names and temperatures:
List[Future[(Float, Location)]]
. But if we want to compare them
together, again without blocking, we want a combined future of all
temps.
val hottest =
for (ts <- Future.sequence(temps))
yield ts.maxBy { _._1 }
hottest()
The value ts
is a future of List[(Float, Location)]
; it is not
available until all the component futures have completed. In the body
of the for expression we’re using maxBy
to find the highest
temperature, the first element of the tuple.
We can generalize this now into a single method which futures to return the name of the hottest city that you give it.
def hottest(locs: Location*) = {
val temps =
for(loc <- locs)
yield for (t <- temperature(loc))
yield (t -> loc)
for (ts <- Future.sequence(temps))
yield ts.maxBy { _._1 }._2
}
When everything goes as expected, that future is fulfilled. The next section is for when things don’t go as expected.