Выполнение последовательности функций, которые возвращают будущее последовательно

У меня есть последовательность функций, которые возвращают будущее. Я хочу выполнить их последовательно, то есть после того, как будет завершено выполнение первой функции в будущем, выполнить следующую функцию и так далее. Есть ли способ сделать это?

ops: Seq [() => Future [Unit]]

3 ответа

Решение

Вы можете объединить все фьючерсы в один с foldLeft а также flatMap:

def executeSequentially(ops: Seq[() => Future[Unit]])(
  implicit exec: ExecutionContext
): Future[Unit] =
  ops.foldLeft(Future.successful(()))((cur, next) => cur.flatMap(_ => next()))

foldLeft обеспечивает порядок слева направо и flatMap дает последовательное выполнение. Функции выполняются с ExecutionContextтак зовет executeSequentially не блокирует И вы можете добавить обратные вызовы или ждать в результате Future когда / если вам это нужно.

Если вы используете Twitter Futureс, тогда я думаю, вам не нужно будет проходить ExecutionContext, но общая идея с foldLeft а также flatMap все еще должен работать.

Если дан Seq[Future[T]], вы можете преобразовать его в Future[Seq[T]] следующим образом:

Val a: Seq[Future[T]] = ???

val resut: Future[Seq[T]] = Future.sequence(a)

немного меньше шаблон, чем выше:)

Я считаю, что это должно сделать это:

import scala.concurrent.{Await, Future}
import scala.concurrent.duration.Duration

def runSequentially(ops: Seq[() => Future[Unit]]): Unit = {
  ops.foreach(f => Await.result(f(), Duration.Inf))
}

Если вы хотите ждать меньше, чем Duration.InfИли остановитесь на неудаче - это должно быть легко сделать.

Другие вопросы по тегам