Future可以抛出调用者捕获的异常吗?

时间:2016-11-25 02:56:13

标签: scala

当我运行下面的代码时它终止并且没有任何反应,有没有办法在future2.map中捕获异常?

object TestFutures1 {
  val future1 = Future { 
    throw new Exception("error") 
    }
}

object TestFutures2 extends App {
  val future2 = TestFutures1.future1
  future2.map { result => println(result) }
  Thread.sleep(5000)
}

2 个答案:

答案 0 :(得分:3)

一般来说,有两种选择(有一些子选项)来处理未来的例外。

  1. 您可以添加一个回调,当将来以异常完成时将调用该回调:

    future2
      .map { result => println(result) }
      .onFailure { exc => 
         exc.printStackTrace
      }
    
  2. 1a上。 .onFailure仅用于副作用,例如,您不能使用它来处理异常。如果你想要处理并拯救未来,你可以使用.recover.recoverWith(两者之间唯一不同的是后者采用的函数返回Future,而前者处理实际结果,与mapflatMap相同的想法:

        future2
          .map(println)
          .recover { case e => 
             e.printStackTrace
             "recovered"
          }.map(println)
    
    1. 另一种选择是等待将来完成,并访问它的结果:

      try {
        // Instead of Thread.sleep - you don't need that:
        Await.result(future2, 2 seconds)
      } catch { case exc => 
        exc.printStackTrace
      }
      

答案 1 :(得分:2)

除了@Dima的回答,也可以使用onComplete来捕捉失败,例如:

  val re = future2.map { result => println(result) }
  re onComplete {
    case Success(s) => ...
    case Failure(e) => e.printStackTrace()
  }