首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >scala期货顺序延迟执行

scala期货顺序延迟执行
EN

Stack Overflow用户
提问于 2016-06-22 08:44:21
回答 2查看 1.5K关注 0票数 3

我有一个期货的iterable,每个期货都返回一个序列:Iterable[Future[Seq[Int]]]作为结果,我需要一个序列,它是从期货:Seq[Int]返回的序列的级联。

问题是,我只需要结果序列的第一个n元素,所以我并不总是需要执行所有的未来。我也不知道需要执行多少期货才能实现这一目标(也许第一个期货会回来,也许我们必须全部执行)。

显然,我需要按顺序执行我的功能。我可以做预测和中断/返回,但我想用功能风格来表达它。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-06-22 09:15:33

下面的工作似乎和‘外观’功能。我的知识有限,这将如何实际执行或行动的引擎盖。

这很容易被输入到def中,其中硬编码的4被传递给一个参数。

我想我应该返回5个元素,尽管只有4个元素被请求,因为对中间未来的评估需要以任何方式进行。丢弃多余的元素应该很简单。

代码语言:javascript
复制
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替换为:

代码语言:javascript
复制
val f = Iterable(Future(Seq(1,2,3)), Future(Seq(4,5)), Future(throw new Exception))

它仍然可以工作,Viktor的调用Future.sequence将一个Iterable[Future_] int转换为Future[Iterable_],因此所有这些都必须完成。

票数 2
EN

Stack Overflow用户

发布于 2016-06-22 15:26:58

要么使用Future.fold:

代码语言:javascript
复制
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)

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37962869

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档