如何获取Future [Seq [Person]]而不是Seq [Future [Person]]

时间:2018-07-31 05:56:33

标签: scala future

我有两个外部呼叫

  1. 哪个给了Future [Seq [People]]
  2. 哪个将person_id并返回person_status作为Future [String]

我需要使用第一个电话中可用序列中的第二个电话来更新每个人的状态。这就是我尝试过的方式,

getFuturePeople.map( (seqPeople : Seq[People]) => {
     seqPeople.map(person => getStatus(person._id).status).map(status => {
     //Update status for this person but I get Seq[Future[Peoson]]
   }) 
})

3 个答案:

答案 0 :(得分:3)

使用可以使用Future.sequence来转换结果,例如:

val futureOfSeq = Future.sequence(seqOfFuture)

答案 1 :(得分:1)

您需要以List的身份遍历Future.traverse

示例

scala> import scala.concurrent.Future
scala> import scala.concurrent.ExecutionContext.Implicits.global

scala> def getFuturePeople = Future { List("Steven", "Wilson", "Michael") }
getFuturePeople: scala.concurrent.Future[List[String]]

scala> def getStatus(name: String) = Future { s"$name updated" }
getStatus: (name: String)scala.concurrent.Future[String]

现在,就像您尝试过的一样,您将获得Future[List[Future[String]]]

scala> getFuturePeople.map { people => people.map { p => getStatus(p) } }
res0: scala.concurrent.Future[List[scala.concurrent.Future[String]]] = Future(Success(List(Future(Success(Steven updated)), Future(Success(Wilson updated)), Future(Success(Michael updated)))))

1)因此,执行list of people ,而不是仅映射到Future.traverse

scala>     val updatedPeople: Future[List[String]] = getFuturePeople.flatMap { people =>
     |       Future.traverse(people) { p =>
     |         getStatus(p)
     |       }
     |     }
updatedPeople: scala.concurrent.Future[List[String]] = Future(<not completed>)

scala> updatedPeople
res5: scala.concurrent.Future[List[String]] = Future(Success(List(Steven updated, Wilson updated, Michael updated)))

2)可行的方法是,一旦您在list of people上映射并获得List[Future[A]],使用Future.sequence转换为Future[List[A]]

scala>     val updatedPeopleUsingSeq: Future[List[String]] = getFuturePeople.flatMap { people =>
     |       Future.sequence {
     |         people.map(getStatus)
     |       }
     |     }
updatedPeopleUsingSeq: scala.concurrent.Future[List[String]] = Future(<not completed>)

scala> updatedPeopleUsingSeq
res6: scala.concurrent.Future[List[String]] = Future(Success(List(Steven updated, Wilson updated, Michael updated)))

答案 2 :(得分:0)

像这样使用Future.sequence:

val returnedFuture :Seq[Future[People]] = Seq(Future.successful(People))

val flattenedFuture:Future[Seq[Peope]] = Future.sequence(returnedFuture)