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?)

+3


source to share


2 answers


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.

+1


source


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.

+2


source







All Articles