future 的值取决于它是否绑定了一个变量?
Value of future depends on whether it has been bound to a variable?
代码:
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
即,在将 future 赋值给变量后检索 future 的值会得到 Some(Success(43))
,而直接检索它会得到 None
。为什么?
另请注意,onComplete
方法产生了预期的行为,尽管它是在 println(fut.map(_ + 1).value)
行之后调用的。
Scala 2.12.0
fut.map(_ + 1)
returns 一个新的 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))
我认为您刚刚遇到了时间问题,因为您没有正确等待期货完成。当 运行 Scala REPL 中的最后一个计算时,它实际上有时会打印 None
,有时会打印 Some(Success(43))
.
但是,如果您运行:
fut.map(_ + 1).onComplete {
case Success(v) => println(v)
case Failure(ex) =>
}
Thread.sleep(100)
它总是会打印 43。当然,您需要确保您的程序不会在 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
即,在将 future 赋值给变量后检索 future 的值会得到 Some(Success(43))
,而直接检索它会得到 None
。为什么?
另请注意,onComplete
方法产生了预期的行为,尽管它是在 println(fut.map(_ + 1).value)
行之后调用的。
Scala 2.12.0
fut.map(_ + 1)
returns 一个新的 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))
我认为您刚刚遇到了时间问题,因为您没有正确等待期货完成。当 运行 Scala REPL 中的最后一个计算时,它实际上有时会打印 None
,有时会打印 Some(Success(43))
.
但是,如果您运行:
fut.map(_ + 1).onComplete {
case Success(v) => println(v)
case Failure(ex) =>
}
Thread.sleep(100)
它总是会打印 43。当然,您需要确保您的程序不会在 future 完成之前终止才能看到结果。