我正在使用
我从这里得到了灵感,但它不够完善,因为当一个失败时,我无法获得成功状态,而在两个失败的情况下,我也无法获得两者的失败状态:failure in Scala future's for comprehension
编辑:另一版本 - 这是一个有效的方法吗?
for
来并行运行2个Future。我想知道哪个成功了,哪个失败了(所有情况都应该运行到完成,要么是结果,要么是失败状态)。目前我只能检索到组合的成功结果。我从这里得到了灵感,但它不够完善,因为当一个失败时,我无法获得成功状态,而在两个失败的情况下,我也无法获得两者的失败状态:failure in Scala future's for comprehension
case class TaggedException(context:String, val throwable: Throwable) extends Exception(throwable.getMessage)
val f1 = Future {...}.recoverWith {case e:Throwable => Future.Failed(new TaggedException("first one failed", e))}
val f2 = Future {...}.recoverWith {case e: Throwable => Future.Failed(new TaggedException("second one failed", e))}
val combinedResult = for {
r1 <- f1
r2 <- f2
} yield (r1,r2)
combinedResult.onFailure {
case e : TaggedException => ... // if both fail I only get the first line in the for
// in case where single fails I only know fail status without the success of the second
}
我想避免这个混乱:
var countCompleted = 0 ... or some other atomic way to count
f1 onComplete {
case Success(value) => {
... countCompleted increment ...
// handle success
if both completed {
// handle returning a status
}
}
case Failure(error) => {
... countCompleted increment ...
// handle failure
if both completed {
// handle returning a status
}
}
}
f2 onComplete {
case Success(value) => {
... countCompleted increment ...
// handle success
if both completed {
// handle returning a status
}
}
case Failure(error) => {
... countCompleted increment ...
// handle failure
if both completed {
// handle returning a status
}
}
}
编辑:另一版本 - 这是一个有效的方法吗?
def toFutureTry[A](future: Future[A]):Future[Try[A]] = future.map(Success(_)).recover {case t: Throwable => Failure(t)}
val fa: Future[Try[Blah]] = toFutureTry(f1)
val fb: Future[Try[Foo]] = toFutureTry(f2)
val combinedRes = for {
ra <- fa
rb <- fb
} yield (ra,rb)
combinedRes.onComplete {
case Success(successRes: (Try[Blah], Try[Foo])) => // all of these cases are success or fails
case Failure(f: Throwable) => // i think it is unused right?
}
Try[A]
包装了内部的thunk,然后在其上使用flatMap
不会短路。 - Yuval ItzchakovList [Future [A]]
实现为Future [List [A]]
的具体实现.. 但这将是非常特定的。 - Yuval Itzchakovdef returnsAFuture() = Future {1/0} val f3 = returnsAFuture() def toFutureTry[T](future: Future[T]) = future.map(Success(_)).recover{case t : Throwable => Failure(t)} val sdf: Future[Try[Int] with Product with Serializable] = toFutureTry(f3) val successFail = f3.map{ Success(_) }.recover { case t: Throwable => Failure(t) }
- Avba