Подтвердить что ты не робот

Какая разница между onComplete и flatMap будущего?

Я пишу приложение Scala, используя драйвер ReactiveMongo. Методы, к которым обращаются к db, всегда возвращаются Future[T]. Являются ли следующие фрагменты кода эквивалентными?

onComplete)

val results: Future[List[Tag]] = Tags.all.toList
results onComplete {
    case Success(list) => //do something with list
    case Failure(t) => //throw the error
}

flatMap)

Tags.all.toList.flatMap(list => //do something with list)

Какая разница?

Плоская карта не бросает неудачу??? И flatMap является обратным вызовом типа onComplete или до тех пор, пока оператор Tags.all.toList не будет завершен?

4b9b3361

Ответ 1

Если вы сомневаетесь, следуйте этим типам.

onComplete возвращает Unit, он позволяет вам что-то делать с результатом Future, но он не вернет значение

flatMap позволяет вам что-то делать со списком и возвращать новый Future

Итак, flatMap намного эффективнее, так как позволяет вам связывать несколько фьючерсов, делать что-то со своими значениями на этом пути и обрабатывать случай сбоя только в самом конце. Чтобы использовать слова Эрика Мейджера: "это ведет вас через счастливый путь".

Так, например, вы можете сделать

val finalFuture = results
 .flatMap(x => /* do something and return a future */)
 .flatMap(y => /* do something else and return a future */)
 .flatMap(z => /* do something else and return a future */)
 .map(myresult => /* do something */)

Если что-то пойдет не так, цепочка сломается раньше, и вы получите первую ошибку.

Это позволяет использовать еще более приятный синтаксис

 val finalFuture = for {
    x <- results
    y <- /* do something and return a future */
    z <- /* do something and return a future */
 } yield something(z)

Если вам нужно обработать случай сбоя, теперь вы можете использовать onComplete или - еще лучше - просто верните Future, поскольку он уже содержит информацию о том, удалось ли выполнить вычисление async или нет.