gpt4 book ai didi

scala - 尽管失败,如何进行执行Future序列?

转载 作者:行者123 更新时间:2023-12-03 11:41:43 24 4
gpt4 key购买 nike

traverse对象中的Future方法在第一次失败时停止。我想要此方法的容忍/宽恕版本,该版本在发生错误时会与其余序列一起进行。

当前,我们已经在utils中添加了以下方法:

def traverseFilteringErrors[A, B <: AnyRef]
(seq: Seq[A])
(f: A => Future[B]): Future[Seq[B]] = {
val sentinelValue = null.asInstanceOf[B]
val allResults = Future.traverse(seq) { x =>
f(x) recover { case _ => sentinelValue }
}
val successfulResults = allResults map { result =>
result.filterNot(_ == sentinelValue)
}
successfulResults
}

有一个更好的方法吗?

最佳答案

真正有用的东西(通常来说)将能够将 future 的错误提升为适当的值(value)。换句话说,将Future[T]转换为Future[Try[T]](成功的返回值变为Success[T],而失败情况变为Failure[T])。这是我们可能的实现方式:

// Can also be done more concisely (but less efficiently) as:
// f.map(Success(_)).recover{ case t: Throwable => Failure( t ) }
// NOTE: you might also want to move this into an enrichment class
def mapValue[T]( f: Future[T] ): Future[Try[T]] = {
val prom = Promise[Try[T]]()
f onComplete prom.success
prom.future
}

现在,如果您执行以下操作:
Future.traverse(seq)( f andThen mapValue )

您将获得成功的 Future[Seq[Try[A]]],其最终值包含每个成功的将来的 Success实例和每个失败的将来的 Failure实例。
如果需要,您可以在此seq上使用 collect删除 Failure实例并仅保留成功的值。

换句话说,您可以按如下方式重写您的辅助方法:
def traverseFilteringErrors[A, B](seq: Seq[A])(f: A => Future[B]): Future[Seq[B]] = {
Future.traverse( seq )( f andThen mapValue ) map ( _ collect{ case Success( x ) => x } )
}

关于scala - 尽管失败,如何进行执行Future序列?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15775824/

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