def f1 = Future(true)
def f2 = Future(false)
case class Test(flag :Boolean= false , id :String)
f1和f2是处理收益的方法
Future[Boolean]
。如果boolean
很容易做f1 && f2
但是我们如何用期货来做到这一点
new Test(id="123").copy(flag = f1 && f2)
不起作用
答案 0 :(得分:4)
您可以使用for-comprehension
从f1和f2的值产生Future,然后使用map/recover
返回派生案例类的Future:
import scala.concurrent.Future
import scala.concurrent.ExecutionContext.Implicits.global
import scala.util.{Try, Success, Failure}
def f1 = Future{ true }
def f2 = Future{ false }
case class Test(flag: Boolean = false, id: String)
val f = for {
x <- f1
y <- f2
} yield x && y
f.map( z => Test(id = "123").copy(flag = z) ).recover{ case e => "Failure: " + e }
// res1: Future[java.io.Serializable] = Future(Success(Test(false,123)))
要捕获容器类型中的成功/失败值,请使map/recover
返回Either[Throwable, Test]
的Future:
f.map( z => Right(Test(id = "123").copy(flag = z)) ).recover{ case e => Left(e) }
// res2: Future[Product with Serializable with Either[Throwable,Test]] =
// Future(Success(Right(Test(false,123))))
或者,使用onComplete
来简单地输出成功/失败值:
f.onComplete{
case Success(z) => println("Success: " + Test(id = "123").copy(flag = z))
case Failure(e) => println("Failure: " + e)
}
// Success: Test(false,123)
或者,使用flatMap/map
代替for-comprehension
:
f1.flatMap(x => f2.map(y => x && y)).
map( z => Test(id = "123").copy(flag = z) ).recover{ case e => "Failure: " + e }
答案 1 :(得分:3)
@LeoC给出了一个相当笼统的答案,但是a specific method可以将两个期货的结果与一个函数结合起来:
f1.zipWith(f2) { _ && _ }
如果我必须在f1为真之后评估f2,如果f1为假,则不应评估f2
那么我怕你需要类似的东西
f1.flatMap { x => if (x) f2 else Future.successful(false) }
至少我目前没有更好的选择。
但是请注意,这不一定好:在第一个解决方案中,f1
和f2
可以同时求值,因此通常比开始之前先评估f1
更快。 f2
。
您还可以对其进行修改,以便两者一起启动,如果一个是false
,则合并后的将来立即以false
结尾,但这甚至是更复杂的代码。