Run Scala Futures in sequential order one after another

For a method that returns Future like this ...

 def myMethod(name: String, count: Int, default: Boolean): Future[Unit] = { ... } 

... I need to call N times, so I defined a list of tuples containing the passed parameters:

 val paramList = List( ("text1", 22, true), ("text2", 55, true), ("text3", 77, false) ) 

How to call myMethod using Future.traverse ?

 Future.traverse(paramList)(myMethod _).tupled(/* how do I pass the current tuple here? */) 
+5
source share
1 answer

Two possible approaches:

 val futuresFromSequence: Future[List[Unit]] = Future.sequence(paramList.map { case (a,b,c) => myMethod(a,b,c) }) val futuresFromTraverse: Future[List[Unit]] = Future.traverse(paramList)(x => x match { case(a,b,c) => myMethod(a,b,c) }) 

Note that traverse takes some set and function from an element of this collection to the future, sequence instead takes a list of futures and reduces them to a future list.

If you want to stick with the tupled syntax (which I personally don't like):

 Future.traverse(paramList)(x => (myMethod _).tupled(x)) 

As noted in the comments, you can run them in sequential order (although this is not 100% clear from the question), in this case you can use foldLeft and flatMap to bind future execution:

 myList.foldLeft(Future(List.empty[Unit]))((prevFuture, currentTuple) => { for { prev <- prevFuture curr <- (myMethod _).tupled(currentTuple) } yield prev :+ curr }) 

In the event that the first generator expects the future in the drive to complete before the launch of a new one, this also returns Future[List[Unit]] .

+10
source

Source: https://habr.com/ru/post/1202716/


All Articles