未来的价值取决于它是否已被变量约束?

时间:2016-12-22 23:34:19

标签: scala future

代码:

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

/**
  * Created by IDEA on 12/23/16.
  */
object Demo extends App {
  val fut = Future {
    Thread.sleep(100)
    21 + 21
  }
  val f = Future { 5 }
  Thread.sleep(200)
  val fut1 = fut.map(_ + 1)
  println(fut1) // Future(Success(43))
  println(fut1.value) // Some(Success(43))
  println(fut.map(_ + 1).value) // None
  fut.map(_ + 1).onComplete {
    case Success(v) => println(v)
    case Failure(e) => println(e)
  } // 43

  (for {
    x <- Future {Thread.sleep(100); 21 + 21}
    y <- Future {Thread.sleep(100); 21 + 22}
  } yield x + y).andThen {
    case Success(v) => println(v)
  }
  Thread.sleep(5000)
}

注意:

之间的区别
println(fut1.value) // Some(Success(43))
println(fut.map(_ + 1).value) // None

即,在将其分配给变量后检索未来的值会给我Some(Success(43)),而直接检索它会给None。为什么呢?

另请注意,onComplete方法会产生预期的行为,尽管它是在println(fut.map(_ + 1).value)行之后调用的。

Scala 2.12.0

2 个答案:

答案 0 :(得分:7)

fut.map(_ + 1)会返回新的Future,其.value可能尚未完成。如果没有,则会显示None println个节目,否则您将获得Some(Success(43))

你可以在REPL中看到这个:

// Paste the body of your Demo object before
// Then repeatedly call the last println:

scala>   println(fut.map(_ + 1).value) // None
Some(Success(43))

scala>   println(fut.map(_ + 1).value) // None
None

scala>   println(fut.map(_ + 1).value) // None
Some(Success(43))

scala>   println(fut.map(_ + 1).value) // None
Some(Success(43))

scala>   println(fut.map(_ + 1).value) // None
None

修改
显示代码的非确定性结果(不对其进行任何更改):

scala> Demo.main(Array())
List()
None
Some(Success(43))

scala> Demo.main(Array())
List()
None
None

scala> Demo.main(Array())
List()
None
None

scala> Demo.main(Array())
Success(43)
Some(Success(43))
Some(Success(43))

答案 1 :(得分:2)

我认为你刚刚遇到时间问题,因为你没有等到期货完成。在Scala REPL中运行最后一次计算时,它实际上有时会打印None,有时会Some(Success(43))

但是,如果您是RAN:

fut.map(_ + 1).onComplete {
  case Success(v) => println(v)
  case Failure(ex) =>
}
Thread.sleep(100)

它将始终打印43.您需要确保您的程序在未来完成之前不会终止,以便查看结果。