【问题标题】:Scala, execute map of futuresScala,执行期货地图
【发布时间】:2016-07-11 00:30:24
【问题描述】:

最好的方法是什么

Map[String, Future[A]]

Map[String, A]

其中 A 是相应未来执行的结果?

这不会编译:

val results = for {
  (key, future) <- myMap
  result <- future
} yield (key, result)

因为我不能将futures 和iterables 混合在一起以便理解。

【问题讨论】:

  • 您确实意识到从Map[String, Future[A]]Map[String, A] 您将别无选择,只能阻止?你的情况可以吗?否则,我认为您真正想要的是从 Map[String, Future[A]]Future[Map[String, A]]
  • @RégisJean-Gilles 好话。这个answer 也包含这样做的提示。

标签: scala dictionary future for-comprehension


【解决方案1】:

可能是这样的:

 map.mapValues { Await.result(_, 5 seconds) }

【讨论】:

  • 您的第二个替代方案无法编译。
  • 确实如此。删除它。
【解决方案2】:

Dima 已经使用Await 给出了答案。但是,当 Future 失败时,它会引发异常。

您可以进一步将类型包装为Try,然后执行.collect 以仅过滤成功的期货(查看官方API)。

import scala.util.{ Try, Success }

val results = myMap
    .map {
        case (key, value) => key => Try(Await.result(value, 5.seconds))
    }
    .collect {
        case (key, Success(value)) => key -> value
    }

通过上面的调用,您会自动丢弃失败的期货并只收集成功的期货。

【讨论】:

  • 这不起作用:映射中的值是Future 类型,与Success 不兼容。问题是,您必须在某个地方阻止并等待,才能从 Future 获得实际(“当前”)结果。
  • 啊哈,确实。我想这次我把它和Try 混在一起了。我已经编辑了我的答案。 collect 仅在您在某处检索结果并将其转换为实际的 Try 后才有效。
【解决方案3】:

如果将其转换为Seq[Future[(String,A)]],则可以使用Future.fold 将其取回单个Future[Map[...]]

def transform[A](m: Map[String, Future[A]]): Future[Map[String, A]] = {
  val seq: Seq[Future[(String, A)]] = m.toSeq.map { case (key, f) =>
    f.map(i => key -> i)
  }

  Future.fold(seq)(Map.empty[String, A])(_ + _)
}

然后照常赎回单身的未来。

【讨论】:

    猜你喜欢
    • 2018-08-04
    • 1970-01-01
    • 2023-03-24
    • 1970-01-01
    • 1970-01-01
    • 2015-04-05
    • 1970-01-01
    • 2019-11-04
    • 2015-08-25
    相关资源
    最近更新 更多