Finagle фильтр последовательности фьючерсов опциона
Я использую twitter finagle
рамки и учитывая последовательность будущих опций, я хотел бы отфильтровать их в зависимости от состояния опции.
seqFuture : Seq[Future[Option[Foo]]]
val filteredFuture = seqFuture map { fut => fut map {
opt => if(opt.isDefined) bar(opt.get)
}
}
Функция bar : Foo => Bar
может быть личность, но я не хочу возвращать Option[Bar]
, Если опция не определена, я хочу, чтобы будущее молча провалилось, и только цепочка дальнейшей обработки выполнялась на фьючерсах, которые содержат определенную опцию.
Я попробовал комбинацию flatten, flatMap, match case Some(_) =>
, но я не приду к их фильтрации. Если я брошу Exception
где опция не определена, вся обработка фьючерсов завершится неудачей (так как я собираю их в какой-то момент)
Я не мог найти решение этой проблемы в руководстве Finagle
Альтернативные решения для фильтрации и связывания фьючерсов с использованием финишной структуры все равно будут оценены.
1 ответ
Проблема с двумя слоями map
здесь (сначала Seq
тогда Future
) этот подход не позволяет вам "пропустить" фьючерсы, которые вычисляют пустые опции.
Если вы используете Future.collect
(обратите внимание, что стандартная библиотека и другие API вызывают эту операцию sequence
), вы можете сделать это как однострочник, а также в конечном итоге с Future[Seq[...]]
что почти всегда лучше, чем Seq[Future[...]]
:
def filteredFuture: Future[Seq[Foo]] = Future.collect(seqFuture).map(_.flatten)
Если вам действительно нужно перейти от Seq[Future[Option[Foo]]]
к Seq[Future[Foo]]
(вместо Future[Seq[Foo]]
вы получаете от collect
Вы неудачливы. Вы можете сделать это, если хотите None
значения приводят к неудачным фьючерсам, но они взрываются, когда вы вызываете что-то вроде collect
вниз, и если вы хотите, чтобы они игнорировались, вам придется явно обрабатывать эти сбои. Я настоятельно рекомендую использовать Future.collect
и идти прямо к Future[Seq[Foo]]
,