我想将我的未来电话运行n次,例如5.未来的“执行”将需要一些时间,我只想在上一次完成时调用新的。类似的东西:
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 :(得分: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
}
这是一种递归解决方案,它将在完成时将期货链接在一起,在达到最大次数时停止链接。这段代码并不完美,但肯定会传达一种可能的解决方案,以确保连续的期货在前一个未来成功完成之前不会触发。
答案 1 :(得分: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())
}