Scala 如何管理一套Akka期货

Scala 如何管理一套Akka期货,scala,functional-programming,future,Scala,Functional Programming,Future,我有一组未来[T],我希望将其管理到我正在编写的库的单个对象中。在我当前的实现中,我使用Future.sequence来收集它们并等待它们解决,这样我就可以在它们上做未来的事情(映射、收集、过滤)。然而,这只会让我有能力在成功或失败时进行匹配,这不一定是我正在处理的期货集合的情况。有些会失败,有些会成功,我希望能够从成功的值中提取我可以提取的值,并收集其他的异常和错误,以便我可以适当地升级它们。在伪代码中,它类似于 Future.sequence(Set[Future[T]]) andThen

我有一组未来[T],我希望将其管理到我正在编写的库的单个对象中。在我当前的实现中,我使用Future.sequence来收集它们并等待它们解决,这样我就可以在它们上做未来的事情(映射、收集、过滤)。然而,这只会让我有能力在成功或失败时进行匹配,这不一定是我正在处理的期货集合的情况。有些会失败,有些会成功,我希望能够从成功的值中提取我可以提取的值,并收集其他的异常和错误,以便我可以适当地升级它们。在伪代码中,它类似于

Future.sequence(Set[Future[T]]) andThen {
  case FullSuccess => "woot"
  case SomeErrors  => "well, that's still ok."
  case FullErrors  => "Ok, who's the wise guy."
}
我真正想要的是在有数据的地方有数据,如果序列中只有一个期货失败,就不必返回完全失败


感谢您的帮助。

不幸的是,您的案例没有内置的帮助程序,但您可以轻松创建自己的帮助程序:

import scala.concurrent.{Await, Future}
import scala.util.{Failure, Success, Try}
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.duration.DurationInt

def sequenceOfTries[T](futures: Seq[Future[T]]): Future[Seq[Try[T]]] =
  futures.foldLeft(Future.successful(List[Try[T]]())) {
    case (accF, f) => accF.flatMap {
      acc => f.map(v => Success(v) :: acc).recover { case ex => Failure(ex) :: acc }
    }
  }.map(_.reverse)


val v = Seq(
  Future.successful(1),
  Future.failed(new IllegalStateException("2")),
  Future.successful(3),
  Future.failed(new IllegalStateException("4"))
)

Await.result(sequenceOfTries(v), 1.second)
结果:

v: Seq[scala.concurrent.Future[Int]] = List(scala.concurrent.impl.Promise$KeptPromise@2416f7e5, scala.concurrent.impl.Promise$KeptPromise@2aaf675d, scala.concurrent.impl.Promise$KeptPromise@360d48f, scala.concurrent.impl.Promise$KeptPromise@230f8be2)    

res0: Seq[scala.util.Try[Int]] = List(Success(1), Failure(java.lang.IllegalStateException: 2), Success(3), Failure(java.lang.IllegalStateException: 4))
UPD。或者,您可以像这样使用
Future.sequence
(结果相同):


将一个可能失败的
Future[T]
转换成一个保证成功的
Future[Try[T]
非常常见,足以证明它自己的助手方法imho是正确的。
def sequenceOfTries[T](futures: Seq[Future[T]]): Future[Seq[Try[T]]] =
  Future.sequence(futures.map(_.map(x => Success(x)).recover { case ex => Failure(ex) }))