使用 _ orElse _ 减少两个期权期货不会产生 Some
Reducing two futures of options with _ orElse _ does not yield Some
受到this question的启发,我认为下面是一个解决方案:
import scala.concurrent.Future
val x: Future[Option[Int]] = Future.successful { None }
val y: Future[Option[Int]] = Future.successful { Some(55) }
Future.reduce(Seq(x, y))(_ orElse _).value // expecting Some(Success(Some(55)))
令我惊讶的是,在 REPL 中执行此操作主要给出 None
,但不规律地给出 Some(55)
:
res80: Option[scala.util.Try[Option[Int]]] = None
res81: Option[scala.util.Try[Option[Int]]] = None
res82: Option[scala.util.Try[Option[Int]]] = None
res83: Option[scala.util.Try[Option[Int]]] = Some(Success(Some(55)))
res84: Option[scala.util.Try[Option[Int]]] = None
所以这对我来说是 Scala WTF 时刻。我错过了什么吗?
显然,两个 future 都已完成并不重要,默认执行上下文可能仍会决定生成结果 future,因此它可能只会在不久之后完成。
Await.result(Future.reduce(Seq(x, y))(_ orElse _), Duration.Inf) // Some(55)
这个较小的代码具有相同的结果:Future(42).value
(有时打印 None
)。
实际上问题在于您如何使用 value
方法(来自 scaladoc):
If the future is not completed the returned value will be None
.
如果你想确定它会产生一个值,你需要等待未来。
受到this question的启发,我认为下面是一个解决方案:
import scala.concurrent.Future
val x: Future[Option[Int]] = Future.successful { None }
val y: Future[Option[Int]] = Future.successful { Some(55) }
Future.reduce(Seq(x, y))(_ orElse _).value // expecting Some(Success(Some(55)))
令我惊讶的是,在 REPL 中执行此操作主要给出 None
,但不规律地给出 Some(55)
:
res80: Option[scala.util.Try[Option[Int]]] = None
res81: Option[scala.util.Try[Option[Int]]] = None
res82: Option[scala.util.Try[Option[Int]]] = None
res83: Option[scala.util.Try[Option[Int]]] = Some(Success(Some(55)))
res84: Option[scala.util.Try[Option[Int]]] = None
所以这对我来说是 Scala WTF 时刻。我错过了什么吗?
显然,两个 future 都已完成并不重要,默认执行上下文可能仍会决定生成结果 future,因此它可能只会在不久之后完成。
Await.result(Future.reduce(Seq(x, y))(_ orElse _), Duration.Inf) // Some(55)
这个较小的代码具有相同的结果:Future(42).value
(有时打印 None
)。
实际上问题在于您如何使用 value
方法(来自 scaladoc):
If the future is not completed the returned value will be
None
.
如果你想确定它会产生一个值,你需要等待未来。