玩 framewoerk 和 scala Future(s) 链。让它更漂亮

play framewoerk & scala Future(s) chain. make it more pretty

我使用 WSClient 提出休息请求。每个请求 return 一些 Future.

因此我需要发出请求 1 并获取一些数据。然后我需要使用来自请求结果 1 的数据发出请求 2。然后我需要使用来自请求结果 2 的数据发出请求 3。等等

在我的代码中它看起来像

def wsChain(data: Data): Future[NewData] = {
    getOne(data).flatMap(data2 => {
      getTwo(data2).flatMap(data3 => {
        getThree(data3).flatMap(data4 => {
          getFour(data4).map(result => foo(result))
        })
      })
    })
  }

这是非常原始的示例,没有对响应和请求进行任何修改。但我认为即使是它也很难阅读。 我现在关于 Await Future,但它是反模式

也许我可以做得更漂亮?没有 N 个内部函数。

这正是 Scala 的 for-comprehensions 旨在帮助解决的情况。您可以用以下代码替换您的代码:

def wsChain(data: Data): Future[NewData] = for {
  data2  <- getOne(data)
  data3  <- getTwo(data2)
  data4  <- getThree(data3)
  result <- getFour(data4)
} yield foo(result)

…编译器会将其脱糖为完全相同的东西。您可以阅读有关 for-comprehensions here 的更多信息,但简而言之,任何时候您发现自己有一个长长的 flatMap 调用链(最后可能是 map ),您应该考虑将它们重写为 for-comprehension,这通过折叠深层嵌套使您的代码更具可读性。