我正在寻找一种将任意长度的Future列表转换为List的Future的方法。我正在使用Play框架,所以最终我真正想要的是
Future [Result]
,但为了简单起见,让我们只说Future [List[Int]]
。通常的做法是使用Future.sequence(...)
,但有一个问题... 我得到的列表通常包含约10-20个Futures,并且其中一个Future失败并不罕见(它们在进行外部web服务请求)。
如果其中一个失败,我不想重新尝试所有Futures,而是只想获取已成功的结果并返回。
例如,下面的操作行不通:
```scala val futures = List(Future.successful(1), Future.failed(new RuntimeException("failed")), Future.successful(2), Future.failed(new RuntimeException("failed"))) val all = Future.sequence(futures) all // this will throw the exception "failed" ```import scala.concurrent._
import scala.concurrent.ExecutionContext.Implicits.global
import scala.util.Success
import scala.util.Failure
val listOfFutures = Future.successful(1) :: Future.failed(new Exception("Failure")) ::
Future.successful(3) :: Nil
val futureOfList = Future.sequence(listOfFutures)
futureOfList onComplete {
case Success(x) => println("Success!!! " + x)
case Failure(ex) => println("Failed !!! " + ex)
}
scala> Failed !!! java.lang.Exception: Failure
我希望能够获得1和3,而不仅仅是异常。我尝试使用Future.fold
,但显然它只是在后台调用Future.sequence
。
Future
,它有一个名为collectToTry
的方法,您只需要过滤成功的即可。https://twitter.github.io/util/docs/com/twitter/util/Future$.html#collectToTry[A](fs:scala.collection.Seq[com.twitter.util.Future[A]]):com.twitter.util.Future[Seq[com.twitter.util.Try[A]]] - rvazquezglez