期货虽然没有依赖性,但仍按顺序执行

时间:2016-06-02 19:20:44

标签: scala

我有以下代码:

  def f1: Future[Unit] = Future {
    Thread sleep 10000
    println("1")
    1
  }

  def f2: Future[Unit] = Future {
    Thread sleep 5
    println("2")
  }

  def f3(x: Unit, y: Unit): Future[Unit] = Future {
    Thread sleep 10
    println("3")
  }

  def main(args: Array[String]): Unit = {

    val f = for {
      r1 <- f1
      r2 <- f2
      r3 <- f3(r1, r2)
    } yield r3

    Await.result(f, Duration.Inf)
  }

f3取决于f2f1

f1f2

之间没有依赖关系

如果我运行代码,我得到:

1
2
3

我希望f1f2f3之前并行运行。 因为f2应该在f1之前终止输出:

2
1
3

我该怎么做?

2 个答案:

答案 0 :(得分:3)

你的理解迫使他们按照这个顺序执行。 for-comprehension实际上是mapflatMapwithFilter函数的语法糖。在您的情况下,只需flatMap。它将扩展到这个表达式:

f1.flatMap(r1 => f2.flatMap(r2 => f3(r1, r2)))

正如您在此处所见,传递给f1.flatMap的函数在f1执行完毕之前不会被调用。

解决这个问题的一个简单方法是在for-comprehension之前实例化期货,如下所示:

val future1 = f1
val future2 = f2

val f = for {
    r1 <- future1
    r2 <- future2
    r3 <- f3(r1, r2)
} yield r3

答案 1 :(得分:2)

val f = f1 zip f2 flatMap f3.tupled

或者,如果您因某种原因坚持使用for理解:

val f = for {
   (r1, r2) <- f1 zip f2
   r3 <- f3(r1, r2)
} yield r3