首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何在失败的情况下继续执行Future sequence?

如何在失败的情况下继续执行Future sequence?
EN

Stack Overflow用户
提问于 2013-04-03 06:49:01
回答 1查看 4.2K关注 0票数 22

来自Future对象的traverse方法在第一次失败时停止。我想要这个方法的容错/容错版本,它在发生错误时继续执行序列的其余部分。

目前我们已经将以下方法添加到我们的工具中:

代码语言:javascript
复制
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
}

有没有更好的方法来做这件事?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-04-03 08:42:08

一个真正有用的东西(通常来说)应该是能够将未来的误差提升到一个适当的值。或者换句话说,将Future[T]转换为Future[Try[T]] (成功的返回值变为Success[T],而失败的情况变为Failure[T])。下面是我们可能实现它的方式:

代码语言:javascript
复制
// 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
}

现在,如果您执行以下操作:

代码语言:javascript
复制
Future.traverse(seq)( f andThen mapValue )

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

换句话说,你可以重写你的助手方法,如下所示:

代码语言:javascript
复制
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 } )
}
票数 23
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15775824

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档