我开始我的一天有一个奇怪的问题。真的看不出我的代码有什么问题。按下面的行
import scala.concurrent._
import scala.concurrent.duration._
import scala.util._
import scala.concurrent.ExecutionContext.Implicits.global
def f2 = Future.failed(new Exception("I do nothing"))
def f1 = Future { println("working"); Thread.sleep(5000); 1 }
val list = List(f2, f1)
val consolidated = Future.sequence(list)
consolidated.onComplete {
case Success(_) => println("completed successfully")
case Failure(e) => println(s"failed with ${e.getMessage}")
}
Await.result(consolidated, Duration.Inf)
并在REPL中执行:paste
。我看到一个奇怪的例外
~ > scala
Welcome to Scala 2.12.1 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_121).
Type in expressions for evaluation. Or try :help.
scala> :paste
// Entering paste mode (ctrl-D to finish)
import scala.concurrent._
import scala.concurrent.duration._
import scala.util._
import scala.concurrent.ExecutionContext.Implicits.global
def f2 = Future.failed(new Exception("no work"))
def f1 = Future { println("working"); Thread.sleep(5000); 1 }
val list = List(f2, f1)
val consolidated = Future.sequence(list)
consolidated.onComplete {
case Success(_) => println("completed successfully")
case Failure(e) => println(s"failed with ${e.getMessage}")
}
Await.result(consolidated, Duration.Inf)
// Exiting paste mode, now interpreting.
java.lang.NoClassDefFoundError: Could not initialize class $line3.$read$$iw$$iw$
at scala.concurrent.impl.CallbackRunnable.run(Promise.scala:60)
at scala.concurrent.impl.ExecutionContextImpl$AdaptedForkJoinTask.exec(ExecutionContextImpl.scala:140)
at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:289)
at java.util.concurrent.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1056)
at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1692)
at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:157)
java.lang.NoClassDefFoundError: Could not initialize class $line3.$read$$iw$$iw$
at scala.runtime.java8.JFunction0$mcI$sp.apply(JFunction0$mcI$sp.java:12)
at scala.concurrent.Future$.$anonfun$apply$1(Future.scala:653)
at scala.util.Success.$anonfun$map$1(Try.scala:251)
at scala.util.Success.map(Try.scala:209)
at scala.concurrent.Future.$anonfun$map$1(Future.scala:287)
at scala.concurrent.impl.Promise.liftedTree1$1(Promise.scala:29)
at scala.concurrent.impl.Promise.$anonfun$transform$1(Promise.scala:29)
at scala.concurrent.impl.CallbackRunnable.run(Promise.scala:60)
at scala.concurrent.impl.ExecutionContextImpl$AdaptedForkJoinTask.exec(ExecutionContextImpl.scala:140)
at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:289)
at java.util.concurrent.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1056)
at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1692)
at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:157)
java.lang.Exception: I do nothing
at .f2(<console>:16)
... 29 elided
scala>
我确实认为没有Could not initialize class
错误的原因。根据我的说法,代码应该打印&#34;失败,没有工作&#34;
答案 0 :(得分:2)
问题是这个
Await.result(consolidated, Duration.Inf)
当您Await
Future
并且该未来失败时,会抛出它包含的异常。由于REPL的工作原理,有一个未被捕获的异常会导致它的某些机制中断。这似乎是REPL中的一个错误,但似乎还没有报道过。
注意,onComplete
不会更改Future
的结果。它只是安排在Future
完成后要完成的事情。特别是,它不会消耗Future
。如果您打算转换Future
,您可以执行以下操作:
val transformed: Future[String] = consolidated.andThen {
case Success(v) => "Completed successfully"
case Failure(e) => s"Failed with ${e.getMessage}"
}
println(Await.result(transformed, Duration.Inf))