等待另一个未来结束返回功能

时间:2017-05-04 19:07:05

标签: scala future

假设我有一个函数func1需要返回一个带有两个整数的Future。这两个值中的每一个都由独立期货返回,如下所示:

def f1 = Future { 1 }
def f2 = Future { 2 }

def func1 : Future[(Int,Int)] = {

    val future1 = f1
    future1.map { result1 =>
       result1 * 10
    }

    val future2 = f2
    future2.map { result2 =>
       result2 * 20
    }

} 

我需要future1等到future2结束(反之亦然)才能将结果作为(Int,Int)返回。如何实现这一目标?

3 个答案:

答案 0 :(得分:4)

这正是期货zip方法的作用:

val futurePair: Future[(Int, Int)] = future1.zip(future2)

请注意,如果您之前没有实例化您的未来(例如,如果future1future2def s,而不是val s),那么这将运行两个并行的计算,而一个for comprehension(或flatMap)会在开始第二个计算之前等待第一个计算成功。

答案 1 :(得分:1)

for - 理解是最好的选择:

scala> import scala.concurrent.Future
import scala.concurrent.Future

scala> import concurrent.ExecutionContext.Implicits.global
import concurrent.ExecutionContext.Implicits.global

scala> def f1 = Future{1}
f1: scala.concurrent.Future[Int]

scala> def f2 = Future{2}
f2: scala.concurrent.Future[Int]

scala> for {result1 <- f1; result2 <- f2} yield (result1 * 10, result2 * 20)
res0: scala.concurrent.Future[(Int, Int)] = scala.concurrent.impl.Promise$DefaultPromise@71f67a79

可以找到更多信息herehere

注意:这将按顺序运行两个Future,而Cyrille Corpet's solution将并行运行它们。

答案 2 :(得分:1)

您可以对已经开始的期货使用for-understandnce:

val f1: Future[Int] = ???
val f2: Future[Int] = ???
val f3: Future[Int] = ???

val futureInts: Future[(Int, Int, Int)] = for {
  result1 <- f1
  result2 <- f2
  result3 <- f3
} yield (result1, result2, result3)

如果期货被分配到lazy valdefs那么这将不起作用,因为期货不会开始(如果你在理解中开始期货,那么他们将按顺序执行)。以下是启动它们,然后使用for等待它们的示例。

示例:

val f1: Future[Int] = Future {
  println("starting f1")
  Thread.sleep(1000)
  1
}
val f2: Future[Int] = Future {
  println("starting f2")
  Thread.sleep(3000)
  2
}
val f3: Future[Int] = Future {
  println("starting f3")
  Thread.sleep(2000)
  3
}

val futureInts: Future[(Int, Int, Int)] = for {
  result1 <- f1
  result2 <- f2
  result3 <- f3
} yield (result1, result2, result3)

futureInts.map {
  case tuple => println(tuple)
}

输出:

starting f1 // These first 
starting f3 // threes statements
starting f2 // happen right away.

(1,2,2)     // Then this prints a three seconds later

在你的情况下,你可以这样做:

def func1 : Future[(Int,Int)] = {

  // Start futures
  val future1 = f1.map(_ * 10)
  val future2 = f2.map(_ * 20)

  // Wait for both futures, and return a tuple
  for {
    result1 <- future1
    result2 <- future2
  } yield (result1, result2)

}