我有2 Future
个Try
,我想只有在两个都成功完成时才会做某事。 Future
都是独立的。所以这里有一些代码
def a1: Future[Try[String]] = Future { Success("a1") }
def a2: Future[Try[Int]] = Future { Success(2) }
val r1 = for {
c1 <- a1
c2 <- a2
} yield (c1, c2)
r1.map {
case tpl: (Success[String], Success[Int]) =>
println("success")
case _ =>
println("failure")
}
这会打印success
。
这个问题是因为我在Tuple2
上进行了模式匹配,因为即使第二个元素是Failure
,第一个case
被执行也会被删除。所以,如果我将a2
更改为
def a2: Future[Try[Int]] = Future { Failure(new InternalError("error")) }
然后再次执行此
val r1 = for {
c1 <- a1
c2 <- a2
} yield (c1, c2)
r1.map {
case tpl: (Success[String], Success[Int]) =>
println("success")
case _ =>
println("failure")
}
现在,即使a2
返回Failure
,上述代码仍会打印success
。我该如何解决?一个非常漂亮的解决方案是使用isInstanceOf[Success[String]]
和isInstanceOf[Success[Int]]
来检查元组的元素并对其真值进行操作但是还有更好的东西吗?
答案 0 :(得分:1)
您可以对元组内容进行模式匹配:
r1.map {
case (_: Success[String], _: Success[Int]) =>
println("success")
case _ =>
println("failure")
}
这样它通过调用元组的unapply
方法,获取元组元素然后检查它们的类型来克服类型擦除。元组元素的运行时类型确实为Success
或Failure
。