如何解决Scala中的期货列表

时间:2013-11-15 23:20:57

标签: scala playframework-2.0 future

我有一个返回Future的调用。 但是,我需要拨打n个电话,这样我才会回来n期货。我想知道如何在继续(不阻塞服务器)之前让所有的解决方案得到解决

例如,

while(counter < numCalls){
    val future = call(counter)
    future.map{  x =>
        //do stuff
    }
    counter += 1 
}

//Now I want to execute code here after ALL the futures are resolved without 
//blocking the server

3 个答案:

答案 0 :(得分:52)

您可以使用Future.sequence(futureList)List[Future[X]]转换为Future[List[X]]。由于后者只是一个简单的Future,您可以在Await.ready或类似帮助者的帮助下等待它完成。

因此,您必须保留您生成的期货清单。类似的东西:

val futures = new ListBuffer[Future[X]]
while(counter < numCalls) {
    val future = call(counter)
    futures += future
    future.map { x =>
        //do stuff
    }
    counter += 1 
}
val f = Future.sequence(futures.toList)
Await.ready(f, Duration.Inf)

你也可以写成:

val futures = (1 to numCalls).map(counter => {
    f = call(counter)
    f.map(x => ...)
    f
})
Await.ready(Future.sequence(futures), Duration.Inf)

答案 1 :(得分:6)

更具功能性:

val futures = for {
  c <- 0 until 10
   } yield {
    val f = call(c) 
    f onSuccess {
      case x =>
      // Do your future stuff with x
    }
    f
  }
Future.sequence(futures)

答案 2 :(得分:5)

我认为你想在期货结束后做点什么,比如说。一个回调,没有阻止原始呼叫?然后你应该做这样的事情:

val futures = for (...) yield {
  future {
  ...
  }
}

val f = Future sequence futures.toList

f onComplete {
  case Success(results) => for (result <- results) doSomething(result)
  case Failure(t) => println("An error has occured: " + t.getMessage)
}

http://docs.scala-lang.org/overviews/core/futures.html

所以你不要阻止await电话,但你仍然等待所有Futures完成,然后对所有结果做一些事情。关键方面是使用Future.sequence将大量未来加在一起,然后使用回调来对结果进行操作。