例如,Folly支持无阻塞组合器collectN,可以在https://github.com/facebook/folly/blob/master/folly/futures/helpers.h
中找到它它没有提供一个非阻塞组合器collectNWithoutException,该组合器只会收集与collectAny类似的成功期货,但会收集多个以上的期货。
Scala似乎只提供firstCompletedOf,其中n == 1时将被collectN。
如果Scala不支持它们,如何轻松实现这些非阻塞组合器? 我想使用现有的组合器来实现。
答案 0 :(得分:2)
这对于大量的期货来说是不切实际的,而是对可用组合器的演示
def firstNCompleted[T](n: Int, futures: List[Future[T]])(implicit executor: ExecutionContext): Future[List[T]] =
Future.firstCompletedOf(futures.combinations(n).map(Future.sequence(_)))
Iterator[List[Future[T]]]
的所有组合Iterator[Future[List[T]]]
的Future中Future[List[T]]
答案 1 :(得分:1)
这里是collectN
:
def collectN[T](n: Int, futures: List[Future[T]]): Future[List[T]] = {
val promise = Promise[List[T]]
var result:List[T] = Nil
futures.foreach {
_.onComplete {
case _ if result.length >= n =>
case Success(t) => synchronized {
result = t :: result
if(result.length == n) promise.success(result.reversed.take(n))
}
case Failure(x) => promise.failure(x)
}
}
promise.future
}
请注意,如果输入期货的数量少于n(并且全部成功),它将返回一个Future
,它将永远不会完成。
您可以对其进行微不足道的修改,以使其一直等到N次成功,而不是在第一次失败后中止,但是如果少于N次的期货最终成功,那也将永远等待。为避免这种情况,您可以计算已经完成的数目,并在达到原始列表的大小后退出。