2017-05-25 56 views
2

你将如何构造一个函数,在这个函数中你既想做副作用又能返回一个值? 例如,我想下面的功能:在Scala函数中处理副作用和返回值的习惯性方法

def futureFromHttpCall: Future[HttpResponse] = 
    doHttpCall.foreach(publishDomainEvent).returnOriginalFuture 

(?不知何故,我有一种感觉,单子会想出这样如果是这样的路径林有点熟悉的猫如果有这个问题的解决方案有)

+0

你想做一些副作用,因为未来的回报,然后返回相同的未来? –

+0

是的,是这种情况 – user3139545

+0

而'publishDomainEvent'是我假设的'Unit'返回方法? –

回答

1

我认为您的未来应该只在您推送所有域名事件时完成。它们也应该是Future。然后,您可以使用Future.sequence等待它们全部完成后再返回。

你的问题有点不清楚,但我认为doHttpCall是一些类型的列表。

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 } 
    } 
} 

所有这些等待在测试时都会非常有帮助。

+0

我喜欢这一点,只是在未来包装我的域名事件 – user3139545

1

我能想到的最简单的事情是不是“隐藏”的Future[T]返回方法中的副作用,揭露它作为未来的一个延续:

def futureFromHttpCall: Future[HttpResponse] = doHttpCall 

然后你既可以onComplete作为副作用:

futureFromHttpCall.onComplete { 
    case Success(_) => publishDomainEvent 
    case Failure(e) => // Stuff 
} 

使效果明确。或者,如果您位于演员系统内部,则可以使用pipeToFuturereceive方法,并在那里处理成功/失败。