scala futures sequential lazy execution
我有一个
问题是我只需要结果序列的第一个
显然,我需要按顺序执行我的功能。我可以做 foreach 和 break/return,但我想用函数式的方式来表达。
以下似乎工作并且"看起来"功能。我对这将如何实际执行或在幕后采取行动的了解有限。
这可以很容易地被放入一个 def 中,其中硬编码的 4 被传递一个参数。
我认为我应该返回 5 个元素,即使只请求了 4 个元素,因为对中间未来的评估需要以任何一种方式进行。删除多余的元素应该很简单。
1 2 3 4 5 6 7 8 9 10 11 12 13 | 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 package在 Future 中只是为了保持一致的类型。
编辑:只是对 viktor 回答的回应(我无法发表评论,因为代表不够高,它稍微增加了我的回答的价值)。
即使 Viktor 的答案更容易阅读,它也必须等待所有 Futures 完成,即使它们不是必需的。
例如,将我的 f 替换为以下内容:
它仍然可以工作,Viktor 调用 Future.sequence 将一个 Iterable[Future[]] 转换为一个 Future[Iterable[]],因此必须完成所有操作。
你要么使用 Future.fold:
1 2 3 4 5 6 7 8 9 |
或者您查看 Future.fold 是如何实现的,然后添加退出条件。 (本质上是一个 foldUntil)