使用 _ 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.

如果你想确定它会产生一个值,你需要等待未来。