在循环中调用Future方法

时间:2016-12-01 02:40:15

标签: scala

鉴于案例类Person定义为:

case class Person ( first: String, middle: String, last: String )

案例类Band包含许多Person s:

case class Band ( name: String, members: List[Person] )

我需要的是为乐队中的每个成员添加Person的中间首字母,同时考虑函数getMiddle实际上是Future。这是我的尝试:

case class Person ( first: String, middle: String, last: String )
case class Band ( name: String, members: List[Person] )

object TestFutures3 extends App {

  val p1 = Person ( "David", "", "Gahan" )
  val p2 = Person ( "Martin", "", "Gore" )
  val band = Band ( "Depeche Mode", List(p1,p2) )

  def getMiddle (name: String) = Future { 
    if (name == "Martin")
      "L"
    else
      "X"
  }

  val membersWithMiddle = band.members.map { 
              p => Person(p.first, getMiddle(p.first).map(_), p.last)
         }  

  println(membersWithMiddle)

  Thread.sleep(5000)
}

2 个答案:

答案 0 :(得分:3)

您可以使用Future.traverse

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

val setMiddleName: Person => Future[Person] =
  member => getMiddle(member.first).map(middle => member.copy(middle = middle))

val bandMembers: Future[List[Person]] =
  Future.traverse(band.members)(setMiddleName)

bandMembers.foreach(println)
// List(Person(David,X,Gahan), Person(Martin,L,Gore))

Future.traverse在这种情况下采用List[Person]Person => Future[Person]函数(将针对每个Person执行 - 除非其中一个Future s失败)并返回Future[List[Person]]

答案 1 :(得分:0)

你可以等待未来,直接分配中间:

val middle = Await.result(getMiddle(p.first), Duration.Inf)
val x: Person = Person(p.first, middle, p.last)

或者你可以回来一个未来的人:

val x: Future[Person] = getMiddle(p.first).map(middle => Person(p.first, middle, p.last)