处理失败的“未来”

时间:2015-07-02 00:54:38

标签: scala

考虑以下两种方法:

def f: Future[Int] = Future { 10 }
def g: Future[Int] = Future { 5 }

我想写一下:

scala> import scala.concurrent.Future
import scala.concurrent.Future

scala> import scala.concurrent.Future._
import scala.concurrent.Future._

scala> import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.ExecutionContext.Implicits.global

scala> for { 
     |   a <- f
     |   b <- g
     | } yield (a+b)
res2: scala.concurrent.Future[Int] = scala.concurrent.impl.Promise$DefaultPromise@34f5090e

现在,我打电话给Await.result,直到它完成为止。

scala> import scala.concurrent.duration._
import scala.concurrent.duration._

正如预期的那样,我得到了15,因为Await.result占用了Future[Int]并返回了Int

scala> Await.result(res2, 5.seconds)
res6: Int = 15

为失败的未来定义recoverFn

scala> val recoverFn: PartialFunction[Throwable, Future[Int]] = 
    { case _ => Future{0} }
recoverFn: PartialFunction[Throwable,scala.concurrent.Future[Int]] = <function1>

我尝试定义failedFuture:

scala> def failedFuture: Future[Int] = Future { 666 }.failed.recoverWith{ recoverFn }
<console>:20: error: type mismatch;
 found   : scala.concurrent.Future[Any]
 required: scala.concurrent.Future[Int]
       def failedFuture: Future[Int] = Future { 666 }.failed.recoverWith{ recoverFn }
                                                                        ^

但是,我得到了上面的编译时错误。

具体来说,我该如何解决这个错误?通常,Future#recoverWith通常是如何处理失败的Future

1 个答案:

答案 0 :(得分:8)

问题是Future#failed 总是返回Future[Throwable]。它的目的只是使Future失败,而是返回Future失败投影。这意味着如果原始Future失败,它将转换为保存异常的成功 Future。如果原始Future成功,则会失败,并保留NoSuchElementException。您收到的错误是因为您实际上正在使用Future[Throwable]恢复Future[Int]Future[Any]的上限最小为Future

如果您只是尝试使用失败的scala> Future.failed[Int](new Exception("???")).recoverWith(recoverFn) res4: scala.concurrent.Future[Int] = scala.concurrent.impl.Promise$DefaultPromise@6933711b scala> res4.value.get res5: scala.util.Try[Int] = Success(0) ,请尝试以下方式:

recoverWith

"[x]", "x", "[y]" 没有任何问题。