2013-10-08 97 views
1

我想運行我未來的呼叫n次,例如5.未來的「執行」需要一些時間,我只想在以前完成時調用新的執行。例如:運行n次

def fun(times: Int): Future[AnyRef] = { 
    def _fun(times: Int) = { 
     createFuture() 
    } 

    (1 to times).foldLeft(_fun)((a,b) => { 
     println(s"Fun: $b of $times") 
     a.flatMap(_ => _fun) 
    }) 
} 

所以我想一次一個地調用「_fun」函數n次。 「createFuture()」需要一些時間,因此在之前的未來完成之前不應再次調用「_fun」。另外,我想創建一個非阻塞解決方案。目前,此代碼執行時不會等待以前的將來結束。

任何想法如何使其工作?

感謝您的回答!

+0

你想讓你的返回類型表示什麼?它是否需要以某種方式彙總鏈接的未來呼叫的結果? – cmbaxter

回答

2

不理解你想最終未來返回什麼(我要去剛剛返回最後完成未來的結果),你可以嘗試這樣的事:

def fun(times: Int): Future[AnyRef] = { 
    val prom = Promise[AnyRef]() 
    def _fun(t: Int) { 

    val fut = createFuture() 
    fut onComplete { 
     case Failure(ex) => prom.failure(ex) 
     case Success(result) if t >= times => prom.success(result) 
     case Success(result) => _fun(t + 1) 
    } 

    } 
    _fun(1) 

    prom.future 
} 

這是一種的遞歸解決方案將在完成時將期貨鏈接在一起,並在達到最大次數時停止鏈接。這個規範並不完美,但是肯定會傳達一種可能的解決方案,以確保在前一個未來成功完成之前,連續期貨不會被觸發。

+0

對不起,忘了指定我想要返回最後的未來或它們的序列,實際上並不那麼重要。您的解決方案按預期工作,謝謝。這對於臨時解決方案來說非常有用,稍後會考慮使它更漂亮:) – psisoyev

0

我認爲使用flatMap進行遞歸會更好。

讓我們想象一下,你有你的createFuture定義爲:

def createFuture() = Future(println("Create future")) 

我們可以創建一個功能組成createFuture與結果:

def compose(f:() => Future[Unit])(b: Future[Unit]) = b.flatMap(_ => f()) 

然後你就可以定義樂趣:

def fun(n : Int) = { 
    def nTimes(n : Int, f : Future[Unit] => Future[Unit], acc : Future[Unit]) = if (n == 0) acc else nTimes(n-1,f,f(acc)) 
    nTimes(n,compose(createFuture),Future()) 
}