在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。