我对scala Future
有疑问。
目前我有一个程序在目录中运行并检查是否有文档。 如果有文件,程序应将这些文件转换为“.pdf”
我的代码看起来像这样(它是伪代码):
for(file <- directory) {
if(timestamp > filetimestamp) {
Future {
// do a convert job that returns UNIT
}
}
}
这是有效代码还是我需要等待返回值?
还有其他替代品与Futures一样轻量级吗?
答案 0 :(得分:9)
要在Future
内转换,只需使用map
和flatMap
即可。当回调完成时,实际操作是异步执行的,但它们是类型安全的。
import scala.concurrent.Future
import scala.concurrent.ExecutionContext.Implicits.global
for(file <- directory) {
if(timestamp > filetimestamp) {
val future = Future {
// do a convert job that returns UNIT
} map {
file => // whatever you want.
}
}
答案 1 :(得分:6)
警告!强> 如果有任何未来会引发'#F; NonFatal&#34;错误,它会被吞噬。使用Future [Unit]时这是一个严重的问题:如果没有代码评估未来,错误就会消失在黑洞中。 (它会影响任何Future [_],但是如果要返回一个值,通常会对它执行某些操作,因此会发现错误。)
scala> import scala.concurrent.ExecutionContext.Implicits.global
scala.concurrent.Future { throw new IllegalArgumentException("foo") }
scala> res16: scala.concurrent.Future[Nothing] = scala.concurrent.impl.Promise$DefaultPromise@64dd3f78
scala> import scala.concurrent.ExecutionContext.Implicits.global
scala.concurrent.Future { throw new IllegalArgumentException("foo"); 42 }
scala> res11: scala.concurrent.Future[Int] = scala.concurrent.impl.Promise$DefaultPromise@65c8295b
完成相同操作的替代方法,但不隐藏错误:
scala> val context = scala.concurrent.ExecutionContext.Implicits.global
context.execute(new Runnable {
def run() = throw new IllegalArgumentException("foo")
})
context: scala.concurrent.ExecutionContextExecutor = scala.concurrent.impl.ExecutionContextImpl@1fff4cac
scala> | | java.lang.IllegalArgumentException: foo
at $line48.$read$$iw$$iw$$iw$$iw$$iw$$iw$$iw$$iw$$iw$$iw$$iw$$iw$$iw$$anon$1.run(<console>:34)
at $line48.$read$$iw$$iw$$iw$$iw$$iw$$iw$$iw$$iw$$iw$$iw$$iw$$iw$$iw$$anon$1.run(<console>:33)
at scala.concurrent.impl.ExecutionContextImpl$$anon$3.exec(ExecutionContextImpl.scala:107)
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)
答案 2 :(得分:0)
是的,这是有效的。将运行您创建的所有Future
,并且将丢弃它们的返回值并收集垃圾。