Бегущее будущее n раз
Я хотел бы выполнить мой будущий вызов 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 до завершения предыдущего будущего. Также я хочу создать неблокирующее решение. В настоящее время этот код выполняется без ожидания завершения предыдущего будущего.
Есть идеи, как заставить это работать?
Спасибо за ваши ответы!
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
}
Это своего рода рекурсивное решение, которое объединяет фьючерсы по завершении, останавливая цепочку, когда достигнуто максимальное количество раз. Этот код не идеален, но, безусловно, содержит одно из возможных решений для обеспечения того, чтобы последующие фьючерсы не сработали, пока не будет успешно завершено предыдущее будущее.
Я думаю, что будет лучше, если вы сделаете это рекурсивным с помощью 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())
}