玩 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,这通过折叠深层嵌套使您的代码更具可读性。
我使用 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,这通过折叠深层嵌套使您的代码更具可读性。