我有一个包含用户的可变地图:
val userMap = mutable.Map.empty[Int, User] // Int is user.Id
现在我需要加载新用户,并将它们添加到地图中。我有以下api方法:
def getNewUsers(): Seq[Int]
def getUser(userId: Int): Future[Option[User]]
所以我首先得到了我需要加载的所有用户:
val newUserIds: Set[Int] = api.getNewUsers
我现在需要加载每个用户,但不知道如何做getUser返回Future [Option [User]]。
我试过了:
api.getNewUsers().map( getUser(_) )
但是返回Set[Future[Option[User]]]
我不确定如何使用Set[Future[Option[User]]]
立即更新我的userMap。
答案 0 :(得分:2)
你必须等待所有的期货完成。您可以使用Future.sequence
将Set[Future[_]]
转换为Future[Set]
,这样您就可以等待它们全部完成:
val s: Set[scala.concurrent.Future[Some[User]]] = Set(Future(Some(User(1))), Future(Some(User(2))))
val f: Future[Set[Some[User]]] = Future.sequence(s)
f.map(users => users.foreach(u => /* your code here */))
然而,使用可变地图可能很危险,因为它可以让自己打开竞争条件。期货在不同的线程中执行,如果你在不同的线程中改变一个可变对象的状态,就会发生不好的事情。
答案 1 :(得分:0)
您可以使用Future.sequence:
将TraversableOnce [Future [A]]转换为 未来[TraversableOnce [A]]。用于将许多期货减少为一个 单一的未来 来自Scala Future
您可以尝试:
val result : Future[Seq[Option[User]]] =
Future.sequence(
api.getNewUsers().map( getUser )
)
result.andThen {
case Success(users) =>
users.flatten.foreach(u => yourMap += u.id -> u)
}