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