Multiple futures in sequence in Scala

I have two calculations that happen in the Future as shown below:

val comp1 = Future { ... }
val comp2 = Future { ... }

      

I want it to run so that comp2 always starts after comp1 finishes! I know that using a for expression I can compose these two Future as.

for {
  comp1Result <- comp1
  comp2Result <- comp2
} yield { ... }

      

What can be the guarantee that comp1 will complete before comp2? I mean this is a computation that happens on a different thread and there is no guarantee that this can be done. Is there a way to guarantee order without blocking?

+3


source to share


1 answer


Scala uses syntactic sugar for comprehension for combinations of flatMap and map calls by container type (Futures in this case), so your code above matches:

comp1.flatMap{ comp1Result => comp2 }

      

the evaluation inside the curly braces only happens here after comp1 completes and returns a successful result (no internal evaluation is performed on failure).

If you define comp2 outside of comprehension for comprehension, as shown in the question, you start this computation then (you just ignore the result until you are inside comprehension), but if you only define it inside comprehension, then it will not run until and before until comp1 completes successfully. So, try to recode your code like this:



val comp1 = Future { ... } // or you could put this construction inside the for as well
for {
  comp1Result <- comp1
  comp2Result <- Future { ... } // Only start the computation here
  comp3Result <- Future { ... } // etc. for as many such computations as you need
} yield { ... }

      

Other alternatives are to declare comp2 as a lazy val (so it is not actually evaluated - starting the computation - until it is specified) or as a lambda (for example val comp2 = () => Future { ... }

) and invoke it with a string

  comp2Result <- comp2()

      

inside understanding.

+4


source







All Articles