繁体   English   中英

Scala:折叠一系列期货的正确方法是什么?

[英]Scala: what is the right way to fold a collection of futures?

我有一段代码可以向一组演员发送广播消息并收集他们的回复。 请看简化代码:

{
  val responses: Set[Future[T] = // ask a set of actors
  val zeroResult: T
  val foldResults: (T, T) => T

  //1. Future.fold(responses)(zeroResult)(foldResults)
  //2. (future(zeroResult) /: responses) { (acc, f) => for { x <- f; xs <- acc } yield foldResults(x, xs) }
} foreach {
   client ! resp(_)
}

然后我注意到代码行1和行为2的行为不同。 例如,有4个演员发送Traversable(1)作为响应,并且

zeroResult = Traversable.empty[Int]
foldResults = { _ ++ _ }

第一行的结果是不同的:通常我得到列表(1,1,1,1),但有时列表(1,1,1)或甚至列表(1,1)。 这对我来说并不奇怪,因为Future.fold是畅通无阻的,所以似乎可能会错过一些回复。

但第二行总是产生四个列表。

任何人都可以解释为什么这些折叠不同,哪个更好?

在你的问题中,对我来说令人惊讶的是,你的第一个折叠(我认为它更简洁的原因)有时似乎在三个(或两个)成功完成的期货清单上运行。

在正常的方案中,未来有3种可能的结果:

  1. 正常完成
  2. 失败(有例外)
  3. 未完成

您提供的两个折叠将产生一个未完成的所有组件期货未完成的未来,或者如果任何未来(或折叠操作)失败,或者如果一切顺利,则完成。 (你的句子Future.fold is unblocking, so it seems some responses could be missed是不正确的。)

我只能认为你有一些其他代码正在完成未来,如果某个超时被破坏没有结果。

除此之外,您已经在第2行的折叠操作中交换了操作数的顺序(应该是yield foldResults(xs, x) ),因此最终的顺序与第1行相反。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM