我有一个期货的iterable,每个期货都返回一个序列:Iterable[Future[Seq[Int]]]作为结果,我需要一个序列,它是从期货:Seq[Int]返回的序列的级联。
问题是,我只需要结果序列的第一个n元素,所以我并不总是需要执行所有的未来。我也不知道需要执行多少期货才能实现这一目标(也许第一个期货会回来,也许我们必须全部执行)。
显然,我需要按顺序执行我的功能。我可以做预测和中断/返回,但我想用功能风格来表达它。
发布于 2016-06-22 09:15:33
下面的工作似乎和‘外观’功能。我的知识有限,这将如何实际执行或行动的引擎盖。
这很容易被输入到def中,其中硬编码的4被传递给一个参数。
我想我应该返回5个元素,尽管只有4个元素被请求,因为对中间未来的评估需要以任何方式进行。丢弃多余的元素应该很简单。
val f = Iterable(Future(Seq(1,2,3)), Future(Seq(4,5)), Future(Seq(6,7,8)))
val output = f.foldLeft(Future(Seq.empty[Int])){(previous, next) =>
previous.flatMap{pSeq =>
if(pSeq.length >= 4) {
Future(pSeq)
} else {
next.map(nSeq => pSeq ++ nSeq)
}
}
}
println(Await.result(output, Duration.Inf)) //List(1,2,3,4,5)我不喜欢的一点是将pSeq包装在未来仅仅是为了保持一致的类型。
编辑:只是对维克托的回答的回应(我不能评论,因为没有足够高的代表,它稍微增加了我的答案的价值)。
尽管维克多的答案更容易读懂,但它必须等待所有的期货完成,即使它们不是必需的。
例如,将我的f替换为:
val f = Iterable(Future(Seq(1,2,3)), Future(Seq(4,5)), Future(throw new Exception))它仍然可以工作,Viktor的调用Future.sequence将一个Iterable[Future_] int转换为Future[Iterable_],因此所有这些都必须完成。
发布于 2016-06-22 15:26:58
要么使用Future.fold:
scala> import scala.concurrent._
scala> import ExecutionContext.Implicits.global
scala> Future.fold(Iterable(Future(Seq(1,2,3)), Future(Seq(4,5)), Future(Seq(6,7,8))))(Seq.empty[Int])( (prev, cur) => if(prev.size >= 4) prev else prev ++ cur) foreach println
List(1, 2, 3, 4, 5)
scala>或者查看Future.fold是如何实现的,并添加了退出条件。(本质上是foldUntil)
https://stackoverflow.com/questions/37962869
复制相似问题