我有一个返回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
答案 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将大量未来加在一起,然后使用回调来对结果进行操作。