scala期货是否实现了例外?

scala期货是否实现了例外?,scala,concurrency,Scala,Concurrency,似乎我错过了scala期货的一些重要概念,我想知道是否有更有经验的人可以带来更多的澄清,因为我现在有点困惑 我在Scala monands上看了Erick Maijer的一些课程: 尝试[T]-可能失败的计算 未来[T]-需要时间且可能失败的计算 我特别关心的是未来可能发生的例外情况,这些例外情况是否转化为失败例外 根据我的尝试,我目前的理解是不正确的,否则类型将是Future[Try[T]] val f = Future{ throw new FileNotFoundException()}

似乎我错过了scala期货的一些重要概念,我想知道是否有更有经验的人可以带来更多的澄清,因为我现在有点困惑

我在Scala monands上看了Erick Maijer的一些课程:

尝试[T]-可能失败的计算

未来[T]-需要时间且可能失败的计算

我特别关心的是未来可能发生的例外情况,这些例外情况是否转化为失败例外

根据我的尝试,我目前的理解是不正确的,否则类型将是Future[Try[T]]

val f = Future{ throw new FileNotFoundException()}
val f2 = f.map{res => "Success"}
val fr =Await.result(f2,30 seconds)
结果:

f: scala.concurrent.Future[Nothing] = scala.concurrent.impl.Promise$DefaultPromise@1e86394
f2: scala.concurrent.Future[String] = scala.concurrent.impl.Promise$DefaultPromise@17dba83
java.io.FileNotFoundException
    at com.ss.rg.service.image.storage.A$A115$A$A115$$anonfun$f$1.apply(StorageTests.sc4056554885605566011.tmp:11)
    at com.ss.rg.service.image.storage.A$A115$A$A115$$anonfun$f$1.apply(StorageTests.sc4056554885605566011.tmp:11)
    at scala.concurrent.impl.Future$PromiseCompletingRunnable.liftedTree1$1(Future.scala:24)
    at scala.concurrent.impl.Future$PromiseCompletingRunnable.run(Future.scala:24)
    at scala.concurrent.impl.ExecutionContextImpl$AdaptedForkJoinTask.exec(ExecutionContextImpl.scala:121)
    at scala.concurrent.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:260)
    at scala.concurrent.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1339)
    at scala.concurrent.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1979)
    at scala.concurrent.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:107)
还是我错过了一些重要的东西。Future正文应为无异常代码,所有异常应通过Future向外传播。失败

正确的实现可能如下所示

val f : Future[String]= {
  val p = Promise[String]
  val ff = Future{
    p.complete(Try(throw new FileNotFoundException()))
  }
  p.future
}
val f2 = f.map{res => "Success"}
val fr =Await.result(f2,30 seconds)
有经验的人能解释一下吗

谢谢

根据对这个问题的反馈,我得出了以下实现。由于我是经验丰富的java开发人员,任何未处理的异常都会让我担心。所以,如果我的理解是正确的,那么下面的实现是可以的,因为任何异常都被转换为Future.failed,nio不需要任何特殊的asfk清理

object LocalStore extends Storage {
  import java.io.FileOutputStream
  import java.nio.ByteBuffer

  override def store(location: String, content: Array[Byte])(implicit exec: Executor): Future[String] = Future {
    require(!location.isEmpty)

    val fout = new FileOutputStream(location)
    val chanell = fout.getChannel
    val buffer = ByteBuffer.allocate(content.length)

    buffer.put(content)
    buffer.flip()
    chanell.write(buffer)
    location
  }
}

如果最后有必要怎么办?scala是否提供了一种处理方法?

FutureonComplete回调有成功也有失败。如果将来发生异常,则将异常设置为失败案例。您的第一个实现是更好的。罪魁祸首是wait.result,如果未来失败,它会抛出异常。我也尝试了这一点,用两种情况下的模式匹配,并打印了其中一种。这是一个相当基本的问题的原因请注意,在内部,未来包装的价值是一个选项[Try[a]],因为它可能尚未完成:问题是什么?