Idiomatic way to handle side effect and return value in Scala functions
How would you build a function where you want to do a side effect and return a value? For example, I would like to use the following function:
def futureFromHttpCall: Future[HttpResponse] =
doHttpCall.foreach(publishDomainEvent).returnOriginalFuture
(somehow I get the feeling that monads will appear, if that's the way I'm a little familiar with cats, if there is a solution to this problem?)
source to share
I think that your future should be completed only when all your events in the domain are migrated. They should also be Future
. You can then use Future.sequence
to wait for all of them to be completed before returning.
Your question is a little unclear, but I'm guessing that doHttpCall is a list of some kind.
def doHttpCall(): Future[Seq[X]] = ???
def publishDomainEvent(x:X): Future[Unit] = ???
def futureFromHttpCall(): Future[Seq[X]] = {
val firstFuture = ???
firstFuture.flatMap { xs =>
val xxs: Seq[Future[Unit]]= xs.map(publishDomainEvent)
Future.sequence(xxs).map { _ => re }
}
}
All this waiting can be very helpful when testing.
source to share
Simplest thing I can think of, instead of "hiding" the side effect inside the return method Future[T]
, show it as a continuation in the future:
def futureFromHttpCall: Future[HttpResponse] = doHttpCall
And then you can either onComplete
on it as a side effect:
futureFromHttpCall.onComplete {
case Success(_) => publishDomainEvent
case Failure(e) => // Stuff
}
Make the effect explicit. Or if you are on an actor's system you can pipeTo
Future
use your method receive
and handle success / failure there.
source to share