Ответ 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 или нет.