Часть, которую вы упускаете, - это понимание хитрого элемента параллелизма, и это то, что порядок исполнения при использовании нескольких фьючерсов не гарантирован. Если ваш блок здесь длительный, потребуется некоторое время, прежде чем добавить счет к scores
// long operation that returns Future[Option[scoreInfo]]
getgeoscore(f).foreach(gso => {
gso.foreach(score => {
// stick a println("here") in here to see what happens, for demonstration purposes only
scores = scores.:+(score)
})
})
Поскольку он выполняется одновременно, ваша функция getscores
также будет одновременно продолжать свою работу, повторяя все остальные inputs
в вашем zipWithindex
. Эта итерация, тем более что это тривиальная работа, вероятно, заканчивается задолго до того, как долгосрочный getgeoscore(f)
завершит выполнение запланированного Future
, и код выйдет из функции, перейдя к следующему коду после вызова *. 1010 *
val futureScores: Future[Seq[scoreInfo]] = getScores(inputs)
futureScores.onComplete{
case Success(scoreInfoSeq) => println(s"Here's the scores: ${scoreInfoSeq.mkString(",")}"
}
//a this point the call to getgeoscore(f) could still be running and finish later, but you will never know
doSomeOtherWork()
Теперь, чтобы очистить это, поскольку вы можете запустить zipWithIndex
для вашего inputs
параметра, я предполагаю, что вы имеете в виду что-то вроде inputs:Seq[Input]
. Если все, что вы хотите сделать, это работать с первым входом, то используйте функцию head
, чтобы только получить первую опцию, так что getgeoscores(inputs.head)
, вам не нужен оставшийся код там.
Также, как примечание, если вы используете Scala, избавьтесь от привычки использовать изменяемые var
s, , особенно , если вы работаете с параллелизмом. Scala основан на поддержке неизменяемости, поэтому, если вы захотите использовать var
, попробуйте использовать val
и посмотрите, как работать с библиотекой коллекций Scala, чтобы она работала.