按顺序运行期货

时间:2016-11-24 14:17:43

标签: scala

以下代码的目标是根据条件执行未来f3f4。请注意,条件取决于Future f1f2的结果,因此必须等待。这似乎有效,但是由于f1f2是期​​货,因此此代码不应按顺序运行。这段代码是否正确?

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)
}

1 个答案:

答案 0 :(得分:2)

不,这不对。当您像创建Future一样创建它时,它会立即开始计算。在达到for理解之前,您的所有4个期货都已经开始运行。您需要稍后创建它们,具体取决于条件。

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 ()

为了便于阅读,最好将一个方法提取到一个方法中,你只需要调用它。

很明显,他们在创建时就会开始运行,因为你可以说

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

它没有任何触发工作。无论如何尝试运行以下代码

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

它应该以随机顺序给你这些数字,而不是顺序3, 2, 1

修改

以下是使用println

的第一个代码(没有flatMap)的实现
val futureCondition = if (y > 0) Future(1) else Future(2)
futureCondition.flatMap(condition => if (condition == 1) Future(3) else Future(4))