gpt4 book ai didi

Scala:列表[Future]到Future[List],忽略失败的 future

转载 作者:行者123 更新时间:2023-12-03 04:40:23 24 4
gpt4 key购买 nike

我正在寻找一种将任意长度的 Future 列表转换为 Future of 列表的方法。我正在使用 Playframework,所以最终我真正想要的是 Future[Result],但为了让事情更简单,我们只说 Future[List[Int]]执行此操作的正常方法是使用 Future.sequence(...) 但有一个转折...我给出的列表通常包含大约 10-20 个 future,而且它是其中一个 future 失败的情况并不罕见(它们正在发出外部 Web 服务请求)。

如果其中一个失败,我不想重试所有这些,而是​​希望能够找到成功的并返回它们。

例如,执行以下操作不起作用:

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 失败。 .recover 是你的 friend ,你可以将它与 map 结合使用,将所有 Future[T] 结果转换为 Future[Try [T]]] 实例,所有这些实例都一定会成功。

注意:您也可以在此处使用 OptionEither,但如果您特别想要,Try 是最简洁的方法陷阱异常

def futureToFutureTry[T](f: Future[T]): Future[Try[T]] =
f.map(Success(_)).recover { case x => Failure(x)}

val listOfFutures = ...
val listOfFutureTrys = listOfFutures.map(futureToFutureTry(_))

然后像以前一样使用 Future.sequence ,给你一个 Future[List[Try[T]]]

val futureListOfTrys = Future.sequence(listOfFutureTrys)

然后过滤:

val futureListOfSuccesses = futureListOfTrys.map(_.filter(_.isSuccess))

如果需要,您甚至可以提取特定的故障:

val futureListOfFailures = futureListOfTrys.map(_.filter(_.isFailure))

关于Scala:列表[Future]到Future[List],忽略失败的 future ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20874186/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com