Это потому, что вы должны явно заблокировать будущее.
В вашем случае основной поток завершается до завершения onComplete
, а иногда до завершения l foreach ..
.
Пожалуйста, добавьте:
import scala.concurrent.{Await, Future}
import scala.concurrent.duration._
val listF = l foreach {
items =>
for(item <- items) println(s"foreach item : $item")
println("\n")
}
Await.result(listF, 5 seconds)
Таким образом, вы будете ждать завершения этого будущего.
Если вы хотите дождаться onComplete
, вам нужно использовать Thread.sleep
(добавить его после onComplete
, например:
l onComplete {
case Success(i) => println(s"SUCCESS : $i")
case Failure(i) => println(s"FAILURE : $i")
}
Thread.sleep(3000)
onComplete
выполняется в некотором потоке в ExecutionContext, тогда как Await
выполняется в текущем потоке и блокирует его до тех пор, пока он не завершится или не истечет указанное время ожидания.
Следовательно, onComplete
неблокирует, а Await
блокирует.
С onComplete
мы не блокируем результат из Future
, но вместо этого мы получим обратный вызов для Success
или Failure
.
Thread.sleep()
блокирует наш основной поток, чтобы мы могли видеть асинхронный результат из будущего.
Обратите внимание, что вы не должны использовать Await.result
в рабочем коде, он используется для тестирования выходных данных Future.
Кроме того, вы наверняка не будете использовать Thread.sleep()
, а вместо этого будете "реагировать" на результат, возвращаемый будущим.
Обычно у вас есть вызов API REST или другой сервис, который запускается и ожидает завершения в будущем.