加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

scala – 如何执行未来序列,尽管失败?

发布时间:2020-12-16 09:35:02 所属栏目:安全 来源:网络整理
导读:来自Future对象的横越方法首先停止。我想要一个容忍/宽恕的方法,发生错误与序列的其余部分。 目前我们已经在我们的utils中添加了以下方法: def traverseFilteringErrors[A,B : AnyRef] (seq: Seq[A]) (f: A = Future[B]): Future[Seq[B]] = { val sentinel
来自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
}

有没有更好的方法来做到这一点?

解决方法

一个真正有用的东西(一般来说)将是能够将未来的错误推广到适当的价值。或者换句话说,将未来转化为未来[Try [T]](成功返回值成为成功[T],而失败案例变为失败[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 )

您将获得一个成功的未来[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 } )
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读