Scala 模式:为了产生未来的理解[A]
Scala Pattern: For Comprehension that Yields a Future[A]
Scala中使用什么模式来处理场景:
你有一堆未来(它们可以是任何东西,但为了举例...)
val aF = Future { true }
val bF = Future { Option(3) }
val cF = Future { myObject }
你有一些功能return未来
def fooF: Future[SomeObject]
我想做这样的事情:
for {
a <- aF
b <- bF
c <- cF
} yield {
if (a) {
// do stuff with b & c
fooF
} else {
Future.successful(SomeObject)
}
}
我想 return 一个 Future[SomeObject]
的值,但是我在 yield 语句中调用 fooF,我会得到一个 Future[Future[SomeObject]]
在 Scala 2.12 中 Future
有一个 flatten
方法:
Creates a new future with one level of nesting flattened, this method is equivalent to flatMap(identity).
所以你可以写for { ... } yield { ... } flatten
.
在 Scala <2.12 中,您可以使用 flatMap(identity)
实现相同的效果(如上所述)
另一种解决方案是使用 flatMap
而不是 for-comprehension:
aF.flatMap { a =>
if (a) {
(bF zip cF).flatMap { (b, c) =>
// do stuff with b & c
fooF
}
} else
Future.successful(SomeObject)
}
}
这是另一个解决方案:
def doStuffWith(a: A, b: B, c: C): Future[SomeObject] = if (a) {
// do stuff with b & c
fooF
} else Future.successful(SomeObject)
for {
a <- aF
b <- bF
c <- cF
d <- doStuffWith(a, b, c)
} yield d
正如@laughedelic 回答中所讨论的,这是一个主观观点,但我相信这种方式更具可读性和可维护性(例如,始终取出函数以对其进行单元测试)。
Scala中使用什么模式来处理场景:
你有一堆未来(它们可以是任何东西,但为了举例...)
val aF = Future { true }
val bF = Future { Option(3) }
val cF = Future { myObject }
你有一些功能return未来
def fooF: Future[SomeObject]
我想做这样的事情:
for {
a <- aF
b <- bF
c <- cF
} yield {
if (a) {
// do stuff with b & c
fooF
} else {
Future.successful(SomeObject)
}
}
我想 return 一个 Future[SomeObject]
的值,但是我在 yield 语句中调用 fooF,我会得到一个 Future[Future[SomeObject]]
在 Scala 2.12 中
Future
有一个flatten
方法:Creates a new future with one level of nesting flattened, this method is equivalent to flatMap(identity).
所以你可以写
for { ... } yield { ... } flatten
.在 Scala <2.12 中,您可以使用
flatMap(identity)
实现相同的效果(如上所述)
另一种解决方案是使用 flatMap
而不是 for-comprehension:
aF.flatMap { a =>
if (a) {
(bF zip cF).flatMap { (b, c) =>
// do stuff with b & c
fooF
}
} else
Future.successful(SomeObject)
}
}
这是另一个解决方案:
def doStuffWith(a: A, b: B, c: C): Future[SomeObject] = if (a) {
// do stuff with b & c
fooF
} else Future.successful(SomeObject)
for {
a <- aF
b <- bF
c <- cF
d <- doStuffWith(a, b, c)
} yield d
正如@laughedelic 回答中所讨论的,这是一个主观观点,但我相信这种方式更具可读性和可维护性(例如,始终取出函数以对其进行单元测试)。