2016-03-23 282 views
1

的地图是什么,从斯卡拉,执行期货

Map[String, Future[A]] 

Map[String, A] 

其中A是对应未来的执行结果的最佳方式?

这不会编译:

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

,因为我可以在相同的理解不能混用期货和iterables。

+2

你意识到从Map [String,Future [A]]到'Map [String,A]'你将别无选择,只能阻止?你的情况好吗?否则,我认为你真正想要的是从Map [String,Future [A]]'到'Future [Map [String,A]]' –

+0

@RégisJean-Gilles好评。这[回答](http://stackoverflow.com/questions/17479160/how-to-convert-mapa-futureb-to-futuremapa-b)包含提示也要这样做。 – ticofab

回答

2

如果你把它转换成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])(_ + _) 
} 

然后赎单的未来为正常。

0

像这样的东西可能:

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

你的第二个选择不会编译。 –

+0

确实。删除它。 – Dima

-1

迪马已经给使用Await答案。但是,如果未来失败,它会引发异常。

您可以将其中的类型进一步包装为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 
    } 

通过上面的调用,您可以自动放弃失败的期货并仅收集成功的期货。

+0

这将不起作用:地图中的值是“Future”类型,与“Success”不兼容。事情是,你必须阻止并等待某个地方,从“未来”到现实(“现在”)的结果。 – Dima

+0

阿哈的确如此。我想这次我将它与'Try'混合。我编辑了我的答案。 'collect'只有在您检索到某个地方的结果并将其转换为实际的'Try'后才能使用。 – bow