应对失败的“未来”

2024-05-15

给出以下两种方法:

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, since Await.result took a 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的处理了吗?


问题是Future#failed always回报Future[Throwable]。它的目的is not简单地失败Future,而是返回一个投影失败那个Future。这意味着如果原来的Future失败,它将被转换为成功的 Future这属于例外情况。而如果原来的Future成功,然后失败,并持有NoSuchElementException。您收到的错误是因为您本质上是在恢复Future[Throwable] with a Future[Int],其最小上限为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.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

应对失败的“未来” 的相关文章

随机推荐