Scala:当一些期货超时时,如何收集期货清单的结果?

时间:2017-01-16 22:26:04

标签: scala future scalaz

我在这种情况下的做法是使用.sequenceF[G[A]]变为G[F[A]]。然后使用Await.result(future_of_a_list, time_out)获取结果。但是,可能有一项任务需要很长时间和时间。在这种情况下,我仍然希望获得其余的结果(同时并行运行所有任务)。可能吗?怎么做?

由于

2 个答案:

答案 0 :(得分:1)

好吧,您可以将每个Await打包到另一个Future

import scala.concurrent.{Await, Future}
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.duration._
import scala.util.Success

scala> val s = Seq(Future(1), Future(2), Future { Thread.sleep(2000); 3 })
s: Seq[scala.concurrent.Future[Int]] = List(Future(Success(1)), Future(Success(2)), Future(<not completed>))

scala> val fs = Future.traverse(s)(f => 
         Future(Await.result(f, 1 second)).transform(Success(_)))
fs: scala.concurrent.Future[Seq[scala.util.Try[Int]]] = Future(<not completed>)

scala> Await.result(fs, Duration.Inf)
res2: Seq[scala.util.Try[Int]] = List(Success(1), Success(2), Failure(java.util.concurrent.TimeoutException: Futures timed out after [1 second]))

答案 1 :(得分:0)

我同意@Kolmar的想法。只是他的解决方案中的transform()是新的Scala 2.12.x版本,而在2.11.x中它有不同的签名。我试图升级但遇到了依赖性问题。我找到了使用2.11.x的fallbackTo的方法。由于我的Await.result(f, 1 second))将返回scalaz.Validation[Throwable, T],因此它也会以这种方式运行:

val fs = Future.traverse(s)(f => 
     Future(Await.result(f, 1 second)).fallbackTo(Future(Failure(new TimeoutException())))