首页 > 解决方案 > 让一个未来等待另一个未来再走

问题描述

我有问题。在运行之前,我需要一个未来来等待另一个未来完成。我的编码是这样的:

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

object Test {

  def foo = Future {
    // take big time to finishing
    Thread.sleep(10000)
    println("Doned foo")
  }

  def bar = Future {
    // some small tasks
    println("Doned bar")
  }

  def main(args: Array[String]): Unit = {
    for {
      _ <- foo
    } yield {
      for {
        _ <- bar
      } yield()
    }
  }

}

当我运行它时,我什么也看不到。怎么了?而 for 循环看起来很糟糕。请提供有关良好解决方案的任何建议。

标签: scala

解决方案


Scala 中的 Future 被急切地评估,没有简单的方法可以让它们变得懒惰。一种方法是将未来的创造包装在功能中,而你就是你所做的,所以你的问题与此无关。

你做错了什么,是你开始你的未来,但是你不等他们,你的应用程序在他们的评估结束之前就完成了。您必须Await.result在方法结束时添加main

您不必要地做的另一件事是嵌套理解。对理解的每次调用都是按顺序完成的(它转换为mapor flatMap),所以bar会等待foo完成。

import scala.concurrent.{Await, Future}
import scala.concurrent.ExecutionContext.Implicits._
import scala.concurrent.duration._

def foo = Future {
    // take big time to finishing
    Thread.sleep(1000)
    println("Doned foo")
}

def bar = Future {
    // some small tasks
    Thread.sleep(1000)
    println("Doned bar")
}

def main(args: Array[String]): Unit = {
    val future = for {
      _ <- foo 
      _ <- bar //this future waits until foo is done
    } yield ()


    Await.result(future, 3000.millis)
}

假设您需要创建执行,其中一个取决于另一个:

def foo1(): Future[String] = ???
def foo2(foo1: String): Future[String] = ??? //foo2 depends on foo1
def foo3(foo2: String): Future[String] = ??? //foo3 depends on foo2

就这么简单:

for {
  f1 <- foo1()
  f2 <- foo2(f1)
  f3 <- foo3(f2)
  _  <- Future{f1 + f2 + f3} //depends on foo1, foo2 and foo3
} yield ()

推荐阅读