[英]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種可能的結果:
您提供的兩個折疊將產生一個未完成的所有組件期貨未完成的未來,或者如果任何未來(或折疊操作)失敗,或者如果一切順利,則完成。 (你的句子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.