Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Future[Future[T]] to Future[T] within another Future.map without using Await?

This is a theoretical question. I have a service I can call to do a job, but that service might not do all of it, and thus I will need to call a second one to finish it.

I was wondering if there is a way to do something similar to this without Await.result the result within the map function:

val myFirstFuture = asyncRequestA()

myFirstFuture.map(result => {
    result match {
       case isWhatIExpected => result
       case isNot => Await.result(asyncRequestB(), someDuration)
    }
})

I would like to "merge" the future given by asyncRequestB() into myFirstFuture without using the Await function to get the result.

Any ideas?

like image 318
le-doude Avatar asked Aug 24 '26 10:08

le-doude


1 Answers

Future is a monad. And the standard way of working with monads in Scala is using a "for comprehension":

for {
  firstResult <- firstFuture
  secondResult <- firstResult match {
    case isWhatIExpected => Future.successful( firstResult )
    case isNot => asyncRequestB()
  }
}
yield secondResult

In Scala "for comprehension" is a syntactic sugar for a series of flatMap, map and filter method applications and under the hood the compiler will expand this comprehension into the same thing as in Regis' answer.

Although in this case you might not exactly see the benefit from using a "for comprehension" syntax, when you drop in another Future and when things start getting trickier, it will come to shine. What "for comprehension" basically does is it flattens the otherwise many levels of nesting of those three method applications.

Secondly, there's also a way you could optimize Regis' solution syntactically, by utilizing "partial functions":

myFirstFuture.flatMap{ 
  case r if isWhatIExpected( r ) => Future.succesful( r )
  case r if isNot( r ) => asyncRequestB()
}
like image 85
Nikita Volkov Avatar answered Aug 27 '26 03:08

Nikita Volkov



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!