在scala中,如何将未来列表转换为返回第一个成功未来的未来?
所有的期货最终都可能成功(有些可能失败),但我们想要第一个成功的期货。并希望将这一结果作为未来来表现。如果列表中的所有期货都失败,那么这个未来将失败 如图所示,在scala中,如何将未来列表转换为返回第一个成功未来的未来?,scala,future,Scala,Future,所有的期货最终都可能成功(有些可能失败),但我们想要第一个成功的期货。并希望将这一结果作为未来来表现。如果列表中的所有期货都失败,那么这个未来将失败 如图所示,提供了Future.firstCompletedOf import scala.concurrent.{ExecutionnContext, Future } def foo[T](f: => Seq[Future[T]])(implicit ec: ExecutionContext): Future[T] = Future.
提供了Future.firstCompletedOf
import scala.concurrent.{ExecutionnContext, Future }
def foo[T](f: => Seq[Future[T]])(implicit ec: ExecutionContext): Future[T] =
Future.firstCompletedOf(f)
像这样返回第一个成功的
def firstSucceededOf[T](futures: List[Future[T]]): Future[T] = {
val p = Promise[T]()
val size = futures.size
val failureCount = new AtomicInteger(0)
futures foreach {
_.onComplete {
case Success(v) => p.trySuccess(v)
case Failure(e) =>
val count = failureCount.incrementAndGet
if (count == size) p.tryFailure(e)
}
}
p.future
}
关键是要理解只完成承诺一次。这是一张工作票
哪个输出
Success(42)
Failure(java.lang.RuntimeException: boom)
如果所有期货交易都以失败告终
val futures = List(
Future(throw new RuntimeException("boom 2")),
Future(throw new RuntimeException("boom 3")),
Future(throw new RuntimeException("boom 1"))
)
它返回最后一次完成的失败
注意Future.firstCompletedOf
返回首次完成(作为成功或失败)不是第一次成功完成:
object FirstSucceededOfExample extends App {
def foo[T](f: => Seq[Future[T]]): Future[T] =
Future.firstCompletedOf(f)
val futures = List(
Future {sleep(2000); -11},
Future {sleep(3000); -7},
Future.failed(new RuntimeException("boom"))
)
foo(futures)
.andThen(v => println(v))
Thread.sleep(1000)
}
哪个输出
Success(42)
Failure(java.lang.RuntimeException: boom)
另一个答案是第一次完成可能是失败。是的,所以这不起作用。应该有第一次成功。复制的和其他的。你可以Future{sleep(n);-11}
w/o parens。