玩framewoerk&scala Future(s)chain.让它更漂亮

Ale*_*ndr 2 scala future playframework ws-client

WSClient用来做休息请求.每个请求都返回一些Future.

结果我需要发出请求1并获取一些数据.然后,我需要做的请求2与请求结果数据1.然后我需要用来自请求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))
        })
      })
    })
  }
Run Code Online (Sandbox Code Playgroud)

这是非常原始的样本,没有任何响应和请求的修改.但我认为即使很难阅读.我现在有关AwaitFuture,但它的反模式

可能我可以做得更漂亮吗?没有N个内部函数.

Tra*_*own 9

这正是Scala的for理解旨在帮助的那种情况.您可以使用以下代码替换代码:

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

......并且编译器会将它完全贬低为完全相同的东西.你可以在这里阅读更多关于for-comprehensions的信息,但简而言之,只要你发现自己有很长的flatMap调用链(也许是map最后一个),你应该考虑将它们重写为一个for理解,这使得你的代码更具可读性坍塌深层筑巢.