Reputation: 1645
I have a sequence of functions that return a future. I want to execute them sequentially i.e. after the first function future is complete, execute the next function and so on. Is there a way to do it?
ops: Seq[() => Future[Unit]]
Upvotes: 1
Views: 1859
Reputation: 180
If given a Seq[Future[T]] you can convert it to a Future[Seq[T]] like so:
Val a: Seq[Future[T]] = ???
val resut: Future[Seq[T]] = Future.sequence(a)
a little less boilerplate than the above :)
Upvotes: 2
Reputation: 14224
You can combine all the futures into a single one with a foldLeft
and flatMap
:
def executeSequentially(ops: Seq[() => Future[Unit]])(
implicit exec: ExecutionContext
): Future[Unit] =
ops.foldLeft(Future.successful(()))((cur, next) => cur.flatMap(_ => next()))
foldLeft
ensures the order from left to right and flatMap
gives sequential execution. Functions are executed with the ExecutionContext
, so calling executeSequentially
is not blocking. And you can add callbacks or await on the resulting Future
when/if you need it.
If you are using Twitter Future
s, then I guess you won't need to pass ExecutionContext
, but the general idea with foldLeft
and flatMap
should still work.
Upvotes: 4
Reputation: 37852
I believe this should do it:
import scala.concurrent.{Await, Future}
import scala.concurrent.duration.Duration
def runSequentially(ops: Seq[() => Future[Unit]]): Unit = {
ops.foreach(f => Await.result(f(), Duration.Inf))
}
If you want to wait less then Duration.Inf
, or stop at failure - should be easy to do.
Upvotes: 0