ps0604
ps0604

Reputation: 1071

Have access in Future.sequence to object that contains Future

I have the following function in Scala:

object TestFutures5 extends App {

  def future (i:Int) = Future { i * 10 }
  var rnd = scala.util.Random

  val futureResult = (1 to 10).map {
     x =>
       val y = rnd.nextInt(x)
      (future(x),y)  // <- this should return a future 
                     // as it needs to be processed by Future.sequence
   }

   Future.sequence(futureResult).foreach(list => println(list)) // <- this does not compile


  Thread.sleep(5000)
}

In Future.sequence function I need to have access to the result of future(x) and to each variable y, but since sequence works only with futures this code does not compile. How to refactor/fix it?

Upvotes: 0

Views: 88

Answers (2)

nmat
nmat

Reputation: 7591

You could just add y to the result of the future:

future(x).map(res => (res, y))

Your sequence will now contain a list of tuples with the result and the value of y

Upvotes: 4

Nagarjuna Pamu
Nagarjuna Pamu

Reputation: 14825

use traverse

Future.traverse(futureResult)(pair => pair._1.map(result => (pair._2, result)))

map each future so that the result will have y value.

Future.traverse(futureResult)(pair => pair._1.map(result => (pair._2, Right(result))).recover { case th => (pair._2, Left(th)) })

To get the y value in case of failure use recover.

So, to summarize it. You are using y as a tag or index for your future computation so that you can know what future with tag failed.

y works as a tag or name to the future.

Scala REPL

scala> Future.traverse(futureResult)(pair => pair._1.map(result => (pair._2, Right(result))).recover { case th => (pair._2, Left(th)) })
result: scala.concurrent.Future[scala.collection.immutable.IndexedSeq[(Int, scala.util.Either[Throwable,Int])]] = Future(<not completed>)

Upvotes: 1

Related Questions