ps0604
ps0604

Reputation: 1081

Sequence of two Future.sequence doesn't work

The objective of this code is to take a sequence of futures, process them with Future.sequence, generate another sequence of futures and process them again with another Future.sequence.

The problem is that it doesn't print anything. What's wrong with this code?

object TestFutures extends App {

  def future (i:Int) = Future { i }
  def future2 (i:Int) = Future { i * 20 }

  val futureResult = (1 to 10).map {
     x => future(x)
   }

  var futureInts = Seq[Future[Int]]()

  Future.sequence(futureResult).map{ list => 
     list.foreach( y => futureInts = futureInts :+ future2(y))
   }

  Future.sequence(futureInts).map { list2 => 
     list2.foreach( z => println(z))
   }


  Thread.sleep(5000)
}

Upvotes: 1

Views: 482

Answers (1)

Yuval Itzchakov
Yuval Itzchakov

Reputation: 149656

It does work, you just have a race condition between the Thread.sleep and the futures finishing execution. You can wait on the futures completion with Await.result:

import scala.concurrent.{Await, Future}
import scala.concurrent.ExecutionContext.Implicits._
import scala.concurrent.duration._

def future(i: Int) = Future.successful(i)
def future2(i: Int) = Future.successful(i * 20)

val futureResult = (1 to 10).map(x => future(x))

val firstResult =
  Future
   .sequence(futureResult)
   .flatMap(list => Future.sequence(list.map(future2))

val sequence = Await.result(firstResult, 10 seconds)

sequence.foreach(println)

Note you should not be synchronously blocking on futures in production code, this is merely for the demonstration that the future does do what you want it to.

Upvotes: 1

Related Questions