Почему этот простой для понимания 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», но на самом деле ничего не происходит.


person sscarduzio    schedule 18.06.2014    source источник
comment
Печатает abc в моем случае ...   -  person Christian    schedule 18.06.2014
comment
Я исправил это, добавив Await.result (res, 3 минуты), где res - значение, назначенное из for.   -  person sscarduzio    schedule 18.06.2014


Ответы (1)


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

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)
  }
}
person Ende Neu    schedule 18.06.2014
comment
Каким-то образом я ожидал, что программа автоматически будет бесконечно ждать завершения фьючерса. Видимо этого не происходит. Я нашел аналогичное решение непосредственно перед вашим ответом (см. Второй комментарий к вопросу). Однако да, я согласен, что это решение. - person sscarduzio; 18.06.2014
comment
Что ж, если бы это было так, вероятно, фьючерсы были бы бесполезны, поскольку основной поток мог бы блокироваться на неопределенное время, ожидая будущего результата: D - person Ende Neu; 18.06.2014
comment
Я согласен, что фьючерсы должны быть асинхронными в целом, но, по крайней мере, основной поток МОЖЕТ дождаться любых незавершенных фьючерсов до завершения. Наверное! - person sscarduzio; 18.06.2014
comment
@sscarduzio Это больше касается ExecutionContext, чем Futures. Вы можете предоставить свой собственный ExecutionContext, который использует не-демонические потоки. - person ggovan; 18.06.2014