Первая функция обратного вызова печатает будущий список почти каждый раз, вторая функция onComplete-callback редко возвращает успех (никогда не бывает неудачной) - PullRequest
1 голос
/ 06 июня 2019

Я рассмотрю несколько примеров из будущего.У меня есть будущее, которое получает список из метода.Я вызываю два различных типа обратных вызовов: обратный вызов Foreach и обратный вызов onComplete, чтобы просто попробовать их.

  • Обратный вызов Foreach почти каждый раз возвращает список.
  • Обратный вызов onComplete редко возвращает SUCCESS, даже если обратный вызов For вернул список.
  • Обратный вызов onCompleteникогда не возвращается FAILURE.

Может кто-нибудь объяснить мне, что происходит?

Я понимаю, что обратные вызовы выполняются одновременно и не имеют порядка.Но если Future возвращает список в Foreach и обратный вызов onComplete был выполнен до Foreach и Future, и он пытался получить список из неудачного Future, не должен ли обратный вызов onComplete вернуть FAILURE?

import scala.concurrent.Future
import scala.concurrent.ExecutionContext.Implicits.global
import scala.util.{Failure, Success}

object FuturesExampleObj extends App {

  println("Using Future to retrieve list\n")
  val l: Future[List[String]] = Future {
    getList()
  }

  println("FOR CALLBACK --------------------\n")

  l foreach {
    items =>
      for(item <- items) println(s"foreach item : $item")
      println("\n")
  }

  println("onComplete CALLBACK --------------------\n")

  l onComplete {
    case Success(i) => println(s"SUCCESS : $i")
    case Failure(i) => println(s"FAILURE : $i")
  }

  def getList(): List[String] ={
    val list = ("a" :: "b" :: "c" :: "d" :: "e":: Nil)
    list
  }
}

Пример результата 1 (общий)

Using Future to retrieve list

FOR CALLBACK --------------------

onComplete CALLBACK --------------------

foreach item : a
foreach item : b
foreach item : c
foreach item : d
foreach item : e



Process finished with exit code 0

Пример результата 2 (необычный)

Using Future to retrieve list

FOR CALLBACK --------------------

onComplete CALLBACK --------------------


Process finished with exit code 0

Пример результата 3 (очень редко)

В основном onComplete никогда не возвращает SUCCESS или FAILURE.Иногда очень редко возвращается «УСПЕХ:» + список.

Ответы [ 2 ]

2 голосов
/ 06 июня 2019

Это потому, что вы должны явно заблокировать будущее. В вашем случае основной поток завершается до завершения 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 или другой сервис, который запускается и ожидает завершения в будущем.

1 голос
/ 06 июня 2019

Причиной этого является завершение потока приложения до окончания Future.

Просто добавьте Await.ready(l, Duration.Inf).value.get в и из вашей программы.

Делайте это только для тестирования!

...