我有一段代码可以向一组演员发送广播消息并收集他们的回复。请查看简化代码:
{
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是畅通无阻的,所以似乎可能会错过一些回应。
但第二行总是产生四个列表。
有谁可以解释为什么这些折叠不同,哪个更好?
答案 0 :(得分:0)
在你的问题中,对我来说令人惊讶的是,你的第一个折叠(我觉得它因其简洁而更可取)有时似乎在三个(或两个)成功完成的期货清单上运作。
在正常的计划中,未来有3种可能的结果:
您提供的两个折叠都会产生一个未完成的未来,而其所有组件期货都已完成,或者如果未来(或折叠操作)失败则会失败,或者如果一切顺利,则会完成。 (你的句子Future.fold is unblocking, so it seems some responses could be missed
不正确。)
我只能认为你的某些其他代码正在完成未来,如果某个超时被破坏就没有结果。
除此之外,你已经在第2行的折叠操作中交换了操作数的顺序(应该是yield foldResults(xs, x)
),所以最后的顺序与第1行相反。