使用失败的期货将List [Future [Int]]转换为Future [List [Int]]

时间:2017-10-10 01:06:01

标签: scala scala-collections

说我有以下代码段

def testFailure2() = {
    val f1 = Future.failed(new Exception("ex1"))
    val f2 = Future.successful(2);
    val f3 = Future.successful((5));
    val f4 = Future.failed(new Exception("ex4"))
    val l = List(f1, f2, f3, f4)
    l
  }

返回类型为List[Future[Int]]。以正常的方式,我可以做Future.sequence并获得List[Future[Int]]。但在这种情况下,由于我的未来失败,它不会起作用。所以我想通过忽略失败的期货将其转换为List [Future [Int]]。我该怎么做?

关于我的类似主题的第二个问题是,我理解filter, collect, partition, etc on a List。在这种情况下,我想filter/partitionlist分成两个列表 - 一个失败的期货 - 在另一个成功完成期货。

我该怎么做?

2 个答案:

答案 0 :(得分:2)

一种方法是首先将所有Future[Int]转换为始终成功的Future[Option[Int]](但如果原始未来失败,则会导致None)。然后,您可以使用Future.sequence,然后展平结果:

def sequenceIgnoringFailures[A](xs: List[Future[A]])(implicit ec: ExecutionContext): Future[List[A]] = {
  val opts = xs.map(_.map(Some(_)).fallbackTo(Future(None)))
  Future.sequence(opts).map(_.flatten)
}

答案 1 :(得分:1)

另一个答案是正确的:你应该使用Future [List [X]],其中X是区分失败和成功的东西。它可以是一个选项,一个,一个尝试,或任何你想要的。

看起来你对此感到困扰,我想这是因为你愿意找到类似的东西:

  • 并行处理所有这些未来,在过程中忽略失败的未来

你得到了

  • 做所有这些未来,等待一切完成,并根据结果丢弃

但实际上,没有特别的方式来表达“忽略失败者”。因为你对它感兴趣所以必须承认每一个未来的结果,否则首先开始它是没有意义的。无论如何,这件事必须等待所有的期货完成。因此,“你现在可以忽略我”的标志确实是选项是无,要么是左,要么尝试失败。对于“这个结果被丢弃”的未来,没有一个特定的标志,我不认为scala需要一个。

所以,不要害怕,并且去Future [List [X]],因为它实际上表达了你想要的东西! : - )