Question

I want to return the list of the computations from a method that uses a list of Futures:

def foo: List[Long] = {
  val res = List(1, 2, 3) map {
    x => Future { someCalculation(x) }
  }

  Future.sequence(res)
  // what to do next?
}


def someCalculation(a: Int): Long = //....

How can I do this?

Was it helpful?

Solution

There is a key point to understand when it comes to futures: if you wanna go from Future[T] to T you need to await the result of the operation, but this is something you would like to avoid not to affect the performance of your program. The correct approach is to keep working with asynchronous abstractions as much as you can, and move blocking up to your calling stack.

The Future class has a number of methods you can use to enchain other async operations, such as map, onComplete, onSuccess, etc etc.

If you really need to wait the result, then there is Await.result

val listOfFutures:List[Future[Long]] =   val res = List(1, 2, 3) map {
    x => Future { someCalculation(x) }
  }

// now we have a Future[List[Long]]
val futureList:Future[List[Long]] = Future.sequence(listOfFutures)

// Keep being async here, compute the results asynchronously. Remember the map function on future allows you to pass a f: A=>B on Future[A] and obtain a Future[B]. Here we call the sum method on the list
val yourOperationAsync:Future[Long] = futureList.map{_.sum}

// Do this only when you need to get the result
val result:Long = Await.result(yourOperationAsync, 1 second)

OTHER TIPS

Well the whole point of using Future is to make it asynchronous. i.e

def foo: Future[List[Long]] = {
  val res = List(1, 2, 3) map {
    x => Future { someCalculation(x) }
  }
  Future.sequence(res)
}

This would be the ideal solution. But In case if you wish to wait, then you could wait for the result and then return:

val ans = Future.sequence(res)
Await.ready(ans, Duration.inf)
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top