简体   繁体   中英

Running futures sequentially

The objective of the code below is to execute Future f3 or f4 depending on a condition. Note that the condition depends on the result of Future f1 or f2 , so it has to wait. This seems to work, however since f1 and f2 are futures this code shouldn't run sequentially. Is this code correct?

object TestFutures extends App {

  val f1 = Future { 1 }
  val f2 = Future { 2 }
  val f3 = Future { 3 }
  val f4 = Future { 4 }

  val y = 1

  for {
    condition <- if (y>0) f1 else f2
    _ <- if (condition==1) f3.map {a => println("333")} else f4.map {b => println("444")}
  }  yield ()


  Thread.sleep(5000)
}

No it is not correct. When you create a Future like you do it, it starts the computations immediately. Before reaching for comprehension, all of your 4 futures are running already. You need to create them later, depending on the conditions.

val y = 1
for {
  condition <- if (y > 0) Future { 1 } else Future { 2 }
  _ <- if (condition == 1) 
    Future { 3 }.map(a => println("333"))
  else 
    Future { 4 }.map(b => println("444"))
} yield ()

It is probably good to extract creating each of those to a method, that you will just call, for sake of readability.

It should be obvious they start running when they are created because you can just say

Future(1).map(x => println(x))

and it works without any sort of triggering. Anyway try to run the following code

import scala.concurrent.Future
import scala.concurrent.ExecutionContext.Implicits.global

def printWhenCompleted[A](f: Future[A]): Future[A] = f.map { x =>
    println(x)
    x
}

val f1 = printWhenCompleted(Future { 1 })
val f2 = printWhenCompleted(Future { 2 })
val f3 = printWhenCompleted(Future { 3 })

for {
  r3 <- f3
  r2 <- f2
  r1 <- f1
} yield r1 + r2 + r3

it should give you those numbers in random order, instead of sequential 3, 2, 1

Edit

Here is implementation of the first code (without println ) using flatMap

val futureCondition = if (y > 0) Future(1) else Future(2)
futureCondition.flatMap(condition => if (condition == 1) Future(3) else Future(4))

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM