sne*_*arb 1 twitter scala future map finagle
我想解决以下问题:
我有一个未来[地图[A,B]].对于所有B,我需要应用一个将B转换为Future [C]的方法,并且我想要回馈Future [Map [A,C]]
这是我到目前为止的代码:
def getClients(clientIds: Seq[Int]): Future[Map[Int, ClientData]] = {
def getClientData(clientInfo: ClientInfo): Future[ClientData] =
clientInfo match {
case ValidInfo(info) => getData(info)
case _ => throw new Exception
}
client.getClients(clientIds) map {
_.toMap map {
case (clientId: Int, clientInfo: ClientInfo) =>
getClientData(clientInfo) map {
clientData => (clientId, clientData)
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
此代码错误,因为它返回Iterable [Future [(Int,ClientData)]]
对于info getClients是一个thrift方法,它返回Map [Map [A,B]],其中Map是可变的,所以我需要首先使用toMap将它转换为不可变的映射.
预先感谢您的帮助!
scala> def f: Future[Map[String, Future[Int]]] = ???
f: Future[Map[String,Future[Int]]]
scala> def x = for {
| m <- f
| i = m.map{ case (k, fv) => fv.map{ k -> _ } }
| l <- Future.sequence(i)
| } yield l.toMap
x: Future[Map[String,Int]]
Run Code Online (Sandbox Code Playgroud)
一步步:
转换Future[Map[A, Future[B]]]为Future[Iterable[Future[(A, B)]]]:
scala> def x1 = f.map{ _.map{ case (k, fv) => fv.map{ k -> _ } } }
x1: Future[Iterable[Future[(String, Int)]]]
Run Code Online (Sandbox Code Playgroud)
转换Iterable[Future[(A, B)]]为Future[Iterable[(A, B)]]和flatten Future[Future[...]]使用flatMap:
scala> def x2 = x1.flatMap{ Future.sequence(_) }
x2: Future[immutable.Iterable[(String, Int)]]
Run Code Online (Sandbox Code Playgroud)
转换Iterable[(A, B)]为Map[A, B]:
scala> def x = x2.map{ _.toMap }
x: Future[Map[String,Int]]
Run Code Online (Sandbox Code Playgroud)
对于com.twitter.util.Future你应该使用collect的,而不是sequence和toSeq之前collect因为它接受Seq:
def x = for {
m <- f
i = m.map{ case (k, fv) => fv.map{ k -> _ } }
l <- Future.collect(i.toSeq)
} yield l.toMap
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
911 次 |
| 最近记录: |