我有一个函数,它接受期货Future[A]*,我希望它返回一个Future[List[A]]。
def singleFuture[T](futures: List[Future[A]]): Future[List[A]] = {
val p = Promise[T]
futures filter { _ onComplete { case x => p complete x /*????*/ } }
p.future
} 我还希望Future[List[A]]类型的结果在上市期货List[Future[A]]完成后立即完成。
那密码不起作用。我认为我应该在这里使用flatMap,因为应该有两个内部循环:一个用于未来,另一个用于承诺。但是怎么做呢?
我不想在这里使用来理解,因为我想从更深的层次来理解这个过程。
发布于 2013-11-29 06:57:28
您可以使用foldRight来实现这一点:
def singleFuture[A](futures: List[Future[A]]): Future[List[A]] = {
val p = Promise[List[A]]()
p.success(List.empty[A])
val f = p.future // a future containing empty list.
futures.foldRight(f) {
(fut, accum) => // foldRight means accumulator is on right.
for {
list <- accum; // take List[A] out of Future[List[A]]
a <- fut // take A out of Future[A]
}
yield (a :: list) // A :: List[A]
}
}如果期货列表中的任何未来失败,<- fut将失败,从而导致accum被设置为失败的未来。
如果要避免使用for,可以将其展开为flatMap,如下所示:
accum.flatMap( list => fut.map(a => a :: list))或者您可以使用异步等待(注意它仍然是一个实验性的特性)。
def singleFuture[T](futures: List[Future[T]]): Future[List[T]] = async {
var localFutures = futures
val result = ListBuffer[T]()
while (localFutures != Nil) {
result += await { localFutures.head }
localFutures = localFutures.tail
}
result.toList
}https://stackoverflow.com/questions/20278133
复制相似问题