Return 来自 Scala foreach 中多个 WS 调用的列表

Return a List from multiple WS calls in a Scala foreach

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

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

我的代码如下,其中 return 是一个空的 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
    }
  }

任何关于如何 return 向我的控制器发送 Future[List] 的建议都很好,谢谢。

使用 monadic for 循环:

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

我不得不猜测您正在使用的确切类型,因此这可能需要调整,但与上述非常相似的东西应该可以解决您的问题。

外层map映射的是原来的future,由于for理解的第一个生成器是一个列表,所以结果也是一个列表。

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)}

至少应该给你一些想法。我们可以在未来的上下文中使用 for comprehension。 Future.traverse 会将未来列表变成列表的未来。需要 return 与用户的连接增加了额外的复杂性,但我们可以映射个人未来以包括与用户的连接。