Scala未来的理解失败 [英] failure in Scala future's for comprehension
问题描述
我有三个连续的期货,并用于这样的理解中
I have three sequential Futures and use in the for comprehension like this
val comF = for {
f1 <- future1
f2 <- future2
f3 <- future3
} yield {
// something
}
comF onSuccess { }
comF onFailure {
// ---------------- Here is the problem --------------------------------
//
// How do I know which future failed(throw exception), when the callback comes here ?
// Thanks for the help! Different futures using different exceptions can solve it.
}
现在我有了一个像List [Future [T]]之类的未来列表,首先我使用此方法将其传输到Future [List [T]](
Now I have a future list like List[Future[T]], and first I transfer it to Future[List[T]] using this method (Why does this list-of-futures to future-of-list transformation compile and work?). then I get the future
val fList: Future[List[T]]
fList on Failure {
//
// How do I know which is Fail now >??
}
推荐答案
考虑代码:
def func = {
try {
val x = maybeThrows
val y = maybeThrowsToo
val z = maybeThrowsAsWell
result(x, y, x)
} catch (RuntimeException e) {
// How do I know which maybeThrows failed?
}
}
Future
情况的工作原理基本上相同.
The Future
case works essentially in the same way.
即使List
中的分组计算也无济于事:
Even grouping computations in List
doesn't help:
def func = {
try {
val x = maybeThrows
val y = maybeThrowsToo
val z = maybeThrowsAsWell
val list = List(x, y, z)
result(list)
} catch (RuntimeException e) {
// How do I know which maybeThrows failed?
}
}
扰流器:您必须跟踪显式的运算失败.如果使用try/catch
完成,将导致一些样板.但幸运的是,使用Future
(和Try
)样板并不坏:
Spoiler: you have to track explicityl which computation failed. It would result in some boilerplate if done with try/catch
. But luckily with Future
(and Try
) the boilerplate isn't that bad:
class TaggedException(val idx, exc: Exception)
def tagFailedWithIndex[T](idx: Int, f: Future[T]): Future[T] =
future recoverWith { case exc => Future.failed(new TaggedException(idx, exc)) }
val comF = for {
f1 <- tagFailedWithIndex(0, future1)
f2 <- tagFailedWithIndex(1, future2)
f3 <- tagFailedWithIndex(2, future3)
} yield something(f1, f2, f3)
comF onFailure {
case exc: TaggedException => "%d computation failed".format(exc.idx)
}
Spoiler ,您必须明确跟踪哪些计算失败.如果使用try/catch
完成,将会导致很多样板.但幸运的是,其中有Try
,而Future
的表现甚至相同:
Spoiler you have to track which computation failed explicitly. It would result in a lot of boilerplate if done with try/catch
. But luckily there is Try
, and Future
behaves even more the same:
class TaggedException(val idx, exc: Exception)
def tagFailedWithIndex[T](idx: Int, f: Future[T]): Future[T] =
future recoverWith { case exc => Future.failed(new TaggedException(idx, exc)) }
val comF = for {
f1 <- tagFailedWithIndex(0, future1)
f2 <- tagFailedWithIndex(1, future2)
f3 <- tagFailedWithIndex(2, future3)
} yield something(f1, f2, f3)
comF onFailure {
case exc: TaggedException => "%d computation failed".format(exc.idx)
}
这篇关于Scala未来的理解失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!