从Scala foreach中的多个WS调用返回一个List

时间:2015-10-27 13:22:53

标签: web-services scala playframework-2.4

我正在对一个返回用户连接列表的服务进行WS调用。在收到响应后,我在列表中执行了foreach,并在foreach中对另一个服务进行了WS调用,以获取每个连接的更多详细信息。

目前我正在尝试使用ListBuffer,但由于调用的异步性质,它会在收集详细信息之前返回为空。

我的代码如下所示,它向我的控制器返回一个空的List

def getAllConnections(username: String) = {
    connectionsConnector.getAllConnections(username).map {
      connections =>
        val connectionsList: ListBuffer[ConnectionsResponse] = ListBuffer()
        connections.map {
          connection =>
            usersService.getUser(connection.connectionUsername).foreach {
              case Some(user) =>
                val blah = ConnectionsResponse(user, connection)
                connectionsList.+=(blah)
            }
        }
        connectionsList.toList
    }
  }

关于如何将Future[List]返回给我的控制器的任何建议都会很棒,谢谢。

2 个答案:

答案 0 :(得分:2)

for {
  connections <- connectionsConnector.getAllConnections(username)
  usersWithConnection <- Future.traverse(connections){ c =>  userService.getUser(c.connectionUsername).map(u => (u,c))  }
} yield usersWithConnection.collect{ case (Some(user), conn) => ConnectionsResponse(user, conn)}

至少应该给你一些想法。我们可以在未来的背景下使用理解。 Future.traverse会将期货清单变成清单的未来。需要与用户一起返回连接会增加额外的复杂性,但我们可以映射个人未来以包括与用户的连接。

答案 1 :(得分:0)

使用monadic for循环:

def getAllConnections(username: String) = connectionsConnector.getAllConnections(username) map { connections ->
    for {
      connection  <- connections
      user        <- usersService.getUser(connection.connectionUsername)
    }
    yield ConnectionsResponse(user, connection)
}

我不得不猜测你正在使用的确切类型,所以这可能需要进行调整,但与上述类似的东西可以解决你的问题。

外部地图映射原始未来,并且由于for comprehension的第一个生成器是一个列表,结果也将是一个列表。