【问题标题】:Dealing with a Failed `Future`处理失败的“未来”
【发布时间】:2015-09-19 08:35:16
【问题描述】:

给定以下两种方法:

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

为失败的 Future 定义 recoverFn

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

我尝试定义一个失败的Future:

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 的?

【问题讨论】:

    标签: scala


    【解决方案1】:

    问题是Future#failed总是返回Future[Throwable]。其目的不是简单地使Future 失败,而是返回该Future失败投影。这意味着如果原来的Future 失败,它将被转换为一个成功Future 持有异常。如果原来的Future 成功了,那么它就变成了失败,并持有一个NoSuchElementException。您遇到的错误是因为您实际上是在使用 Future[Int] 恢复 Future[Throwable],它的上限至少为 Future[Any]

    如果你只是想玩失败的Futures,试试这个吧:

    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 没有错。

    【讨论】:

      猜你喜欢
      • 2020-12-28
      • 2015-03-12
      • 2020-11-11
      • 2018-01-19
      • 2020-10-15
      • 2023-01-06
      • 2015-10-28
      • 2016-06-30
      • 2014-06-24
      相关资源
      最近更新 更多