Почему этот простой Scala для понимания не выполняет фьючерсы?

#scala #future #for-comprehension

#scala #будущее #для понимания

Вопрос:

Я застрял, выясняя, почему это не работает:

 import scala.concurrent.future
import scala.concurrent.Future
import scala.concurrent.ExecutionContext

import scala.concurrent.ExecutionContext.Implicits.global

object FutureTest {

  def main(args: Array[String]) {
    val result1 = future("a")
    val result2 = future("b")
    val result3 = future("c")

    val res = for {
      r1 <- result1
      r2 <- result2
      r3 <- result3
    } yield (r1   r2   r3)

    for { r <- res} yield(println(r))
  }
}
  

Я ожидаю, что это напечатает «abc», но на самом деле ничего не происходит.

Комментарии:

1. В моем случае выводит «abc»…

2. Я исправил это, добавив Await.result(res, 3 минуты), где res — значение, назначенное из for .

Ответ №1:

Вы выполняете автономную программу, и проблема в том, что основной поток завершается до завершения future, чтобы увидеть что-то, что вы могли бы использовать это:

 import scala.concurrent.future
import scala.concurrent.Future
import scala.concurrent.ExecutionContext

import scala.concurrent.ExecutionContext.Implicits.global

object FutureTest {

  def main(args: Array[String]) {
    val result1 = future("a")
    val result2 = future("b")
    val result3 = future("c")

    val res = for {
      r1 <- result1
      r2 <- result2
      r3 <- result3
    } yield (r1   r2   r3)

    val printing = for { r <- res} yield(println(r))

    Await.ready(printing, Duration.Inf)
  }
}
  

Комментарии:

1. Почему-то я ожидал, что программа автоматически будет бесконечно ждать завершения фьючерсов. По-видимому, этого не происходит. Я нашел аналогичное решение непосредственно перед вашим ответом (см. Второй комментарий к вопросу). Однако да, я согласен, что это решение.

2. Ну, если бы это было так, то, вероятно, фьючерсы были бы бесполезны, поскольку основной поток мог бы блокироваться на неопределенный срок в ожидании будущего результата: D

3. Я согласен, что фьючерсы вообще должны быть асинхронными, но, по крайней мере, основной поток МОЖЕТ дождаться любых незавершенных фьючерсов до завершения. Я думаю!

4. @sscarduzio Это больше касается ExecutionContext, чем Futures . Вы можете предоставить свой собственный ExecutionContext, который использует потоки, отличные от демонов.