似乎我错过了scala期货的一些重要概念,如果有经验的人可以带来更多的澄清,我会恭维,因为我现在有点困惑。
我在Scala monands上观看了Erick Maijer的一些课程:
尝试[T] - 可能失败的计算
Future [T] - 需要时间并可能失败的计算
我特别关注可能在Future中发生的Exception,那些转换为Failed(异常)吗?
根据我的尝试,我目前的理解是不正确的,否则类型将是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.failed传播到外部吗?
正确的实施可能如下
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开发人员,所以任何unhandeled Exception让我担心。因此,如果我的下划线是正确的,那么实现后就可以了,因为任何异常都转换为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是否提供了如何处理它的方法?