2017-05-25 53 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方法,並在那裏處理成功/失敗。