将 Future[Option[Option[T]]] 中的 Option 部分展平。

3

我有一个包含(并行)计算的results:List [Future [Option [T]]]

我想尽快获得第一个非None结果,或者如果所有计算都返回None,则返回None

目前,我正在处理Future.find找不到任何结果的情况,我认为这很丑陋。

Future.find(results)(r => r.isDefined) map { 
  case Some(hit) => hit
  case _ => None
}

我希望得到一个Future[Option[T]],这是我想要的。

是否有一种更简洁的方式来获得Future[Option[T]]:即不需要手动展平Future[Option[Option[T]]]


你能否在Futures中构建计算结构,以便使用Future.firstCompletedOf获取所需内容? - Randall Schulz
@RandallSchulz 我不知道有没有这样的情况... 这些计算可能会返回 None,而我不知道哪些会这样做(实际上,如果我事先知道,我就永远不会开始这个计算)。 - fommil
1个回答

1
相比于专门针对选项的处理,您可以编写一个通用函数,例如:
def collectFirst[A, B](futures: List[Future[A]])(pfn: PartialFunction[A, B])
    (implicit ex: ExecutionContext): Future[Option[B]] =
  Future.find(futures)(pfn.isDefinedAt) map (_.collect(pfn))

关于这一点,您可以重新表述您的问题为:
collectFirst(results) { case Some(hit) => hit }

嗯,我不喜欢在同一个pfn上使用isDefinedAtcollect调用。 - fommil
可以安全地将 collect 替换为 map,因为如果 find 的内部结果是 Some,那么我们已经知道该值内部的 pfn 已经被定义。 - Ben James

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接