我使用Playframework,所以最终,我真正想要的是 Future[Result]
,但是为了简单起见,让我们说 Future[List[Int]]
这样做的正常方法是使用 Future.sequence(...)
但是's a twist... The list I' m通常有大约10-20个期货在它中,它希望能够获得那些成功并返回那些的东西 .
例如,执行以下操作不起作用
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
.
在此先感谢您的帮助!
5 回答
诀窍是首先确保没有一个未来失败 .
.recover
在这里是你的朋友,你可以将它与map
结合起来将所有的Future[T]
结果转换为Future[Try[T]]]
个实例,所有这些都肯定是成功的期货 .注意:您也可以使用
Option
或Either
,但如果您特别想要捕获异常,Try
是最干净的方法然后像以前一样使用
Future.sequence
,给你一个Future[List[Try[T]]]
然后筛选:
如果需要,您甚至可以提取特定的故障:
我试过凯文的答案,我在我的Scala版本(2.11.5)上遇到了一个小故障......我纠正了这个问题,如果有人有兴趣的话还写了一些额外的测试......这是我的版本>
我刚刚遇到了这个问题并提供了另一种解决方案:
这里的想法是,在折叠中,您正在等待列表中的下一个元素完成(使用for-comprehension语法),如果下一个元素失败,您只需回退到已有的内容 .
您可以使用选项轻松包装未来结果,然后展平列表:
Scala 2.12在
Future.transform
上有一个改进,它适用于代码较少的anwser .