def testThrowException(number: Int): Future[Int] = {
if (number == 0) {
throw new Exception("number is 0")
else {
Future{1}
}
Run Code Online (Sandbox Code Playgroud)
对于上述函数,如果我用 testThrowException(0) 调用它,我可以看到控制台中打印的异常错误消息,但如果我执行类似的操作
def testThrowException(number: Int): Future[Int] = {
anotherFuture.map {
if (number == 0) {
throw new Exception("number is 0")
} else {
1
}
}
Run Code Online (Sandbox Code Playgroud)
我看不到控制台中打印的异常,但是如果我执行 testThrowException.onFailure,我可以看到失败消息,我在这里做错了什么吗?为什么不打印出异常
Future在一个单独的线程中运行,因此将 a 扔进去Future只会使该线程崩溃,同时保持主线程运行。例如,
object Hello extends App {
println(s"Starting in main thread called ${Thread.currentThread.getName}...")
Future(
throw new RuntimeException(s"I crashed separate thread called ${Thread.currentThread.getName}")
).andThen { case Failure(e) => println(e.getMessage) }
println("I made it!")
}
Run Code Online (Sandbox Code Playgroud)
应该输出
Starting in main thread called run-main-e...
I made it!
I crashed separate thread called scala-execution-context-global-253
Run Code Online (Sandbox Code Playgroud)
我们看到它scala-execution-context-global-253在主线程run-main-e保持运行的同时崩溃了单独的线程,所以I made it!打印得很好。另一方面,下面的例子抛出了一个Future
object Hello extends App {
println(s"Starting in main thread called ${Thread.currentThread.getName}...")
throw new RuntimeException(s"I crashed the main thread ${Thread.currentThread.getName}")
println("I made it!")
}
Run Code Online (Sandbox Code Playgroud)
哪个输出
Starting in main thread called run-main-d...
[error] (run-main-d) java.lang.RuntimeException: I crashed the main thread run-main-d
Run Code Online (Sandbox Code Playgroud)
我们看到主线程run-main-d崩溃之前I made it!可以打印。
第一个函数testThrowException在获取 a 作为输入的情况下不会返回 Future 0。因此,程序会一直运行,直到出现异常。
然而,如下面粘贴的源代码所示,Future.map总是返回另一个 future:
def map[S](f: T => S)(implicit executor: ExecutionContext): Future[S] = { // transform(f, identity)
val p = Promise[S]()
onComplete { v => p complete (v map f) }
p.future
}
Run Code Online (Sandbox Code Playgroud)
仅定义 Future 不会打印其结果,也不会打印抛出的异常。您需要定义onSuccess、onFailure、 或onComplete来执行此操作。但是,如果 Future 的主体中存在 print 语句,那么它将执行:
def addOne(number: Int): Int = {
if (number == 0) {
// you can also print the exception instead of just throwing it.
throw new Exception("number is 0")
} else {
println("success")
1 + number
}
}
Future { addOne(1) } // scala.concurrent.Future[Int] = Future(Success(2))
// the above also prints "success"
Future { addOne(0) } // scala.concurrent.Future[Int] = Future(Failure(java.lang.Exception: number is 0))
// the above does not print anything unless the exception is printed before thrown in `addOne`
Run Code Online (Sandbox Code Playgroud)
您还可以使用onComplete, 来处理成功和/或失败:
// prints "got error" plus the stack trace
- List item
Future {0}.map(addOne).onComplete {
case Success(value) => println(s"got $value")
case Failure(t) => println("got error: " + t.getStackTrace.mkString("\n"))
}
Run Code Online (Sandbox Code Playgroud)
请注意,使用的进口是:
import scala.concurrent.Future
import scala.concurrent.ExecutionContext.Implicits.global
import scala.util.{Failure, Success}
Run Code Online (Sandbox Code Playgroud)