0
votes

I read about Scala Futures and Promises.

I know that I can use callbacks, the flatMap combinator or a for-comprehension to chain futures. When a future is completed, another future is started and so on.

Is there a way to chain the execution of an arbitrary number of futures, stored in a Scala Collection (for example a List)? I tried to invoke Future.sequence on this list of futures but they start all together and they are executed concurrently (not sequentially).

2
Your solution is here: stackoverflow.com/a/20415056/5123895 you need to provide list of items and function that can translate each of them into future, similarly to Future.traverse, but this will run sequentially. If you already have a list of futures then you have a problem because it's too late, they are already running.Łukasz
I have tried with the solution reported in that link and it works. I read it before writing my post but it wasn't clear for me. Your explanation in the comment helped me to understand it. ThanksMattia Micomonaco

2 Answers

4
votes

My answer is more care about how to deal a list of arbitrary number of Scala Futures function.

  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) }
  }

In the above code snippet, create a compose method and with high order Future function parameters. and this method iterate all high order functions and compose a full new Future function.

Example Use:

  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
0
votes
def chainFutures(list: List[() => Future[Any]]): Future[Any] = {
  list match {
    case x :: Nil => Future.successful(x)
    case (x :: xs) => x() flatMap (_ => chainFutures(xs))
  }
}

this should do what you want, if you can accept to provide a list of functions that return a Future. The problem with a List[Future[_]] is, that they are already started, so they cant be chained in terms of execution. Except you provide a single thread ExecutionContext.

In case of failure, it returns the first failure and stops executing the other futures.