【问题标题】:Sequential execution of a list of an arbitrary number of Scala Futures顺序执行任意数量的 Scala Futures 列表
【发布时间】:2016-08-21 09:06:41
【问题描述】:

我读到了Scala Futures and Promises

我知道我可以使用回调、flatMap 组合器或 for-comprehension 来链接期货。当一个future完成时,另一个future开始,依此类推。

有没有办法链接任意数量的期货的执行,存储在 Scala 集合中(例如List)? 我试图在这个期货列表上调用Future.sequence,但它们是一起开始的,并且是同时执行的(不是顺序执行的)。

【问题讨论】:

  • 您的解决方案在这里:stackoverflow.com/a/20415056/5123895 您需要提供可以将每个项目转换为未来的项目列表和函数,类似于 Future.traverse,但这将按顺序运行。如果您已经有一个期货列表,那么您就有问题了,因为为时已晚,它们已经在运行。
  • 我已尝试使用该链接中报告的解决方案并且它有效。我在写我的帖子之前阅读了它,但对我来说并不清楚。您在评论中的解释帮助我理解了它。谢谢

标签: scala promise future


【解决方案1】:

我的回答更关心如何处理任意数量的 Scala Futures 函数列表。

  type FUTURE_FUNCTION = String => Future[String]

  def compose(fs: List[FUTURE_FUNCTION]): FUTURE_FUNCTION = fs match {
    case List(head) => head
    case head :: tail => head(_).flatMap { u => compose(tail)(u) }
  }

在上面的代码sn-p中,创建一个compose方法高阶Future函数参数。而且这个方法会迭代所有的高阶函数,组成一个全新的Future函数。

使用示例:

  val f1: String => Future[String] =
    (s: String) => Future {
      s.toUpperCase
    }


  val f2: String => Future[String] =
    (s: String) => Future {
      s + " Hello World"
    }

  compose(List(f1, f2))("foo bar")
  > FOO BAR Hello World

【讨论】:

  • 我已经尝试过@Łukasz 在评论中建议的解决方案here。它有效,并且在概念上与您的解决方案相似。我无法提前创建期货列表,但我需要一个函数来从“项目”中获取未来。谢谢
【解决方案2】:
def chainFutures(list: List[() => Future[Any]]): Future[Any] = {
  list match {
    case x :: Nil => Future.successful(x)
    case (x :: xs) => x() flatMap (_ => chainFutures(xs))
  }
}

如果您可以接受提供返回 Future 的函数列表,这应该可以满足您的要求。 List[Future[_]] 的问题是,它们已经启动,因此它们不能在执行方面被链接起来。除非您提供单个线程 ExecutionContext

如果失败,则返回第一个失败并停止执行其他期货。

【讨论】:

  • 这根本不符合要求,当您传递期货列表时,它们都已经启动并并行运行。它不会累积结果。你在 xs 上调用 tail,而你可能指的是已经是列表尾部的 xs。
  • 我发现至少要回答有关解决您问题的问题。请参阅对您问题的评论中的链接
猜你喜欢
  • 1970-01-01
  • 2019-03-26
  • 1970-01-01
  • 2012-11-29
  • 1970-01-01
  • 2019-11-04
  • 2012-01-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多