未来/承诺无需等待结果?返回单位

时间:2014-02-03 14:59:53

标签: scala concurrency future

我对scala Future有疑问。

目前我有一个程序在目录中运行并检查是否有文档。 如果有文件,程序应将这些文件转换为“.pdf”

我的代码看起来像这样(它是伪代码):

for(file <- directory) {
  if(timestamp > filetimestamp) {
    Future {
    // do a convert job that returns UNIT
    }
  }
}

这是有效代码还是我需要等待返回值?

还有其他替代品与Futures一样轻量级吗?

3 个答案:

答案 0 :(得分:9)

要在Future内转换,只需使用mapflatMap即可。当回调完成时,实际操作是异步执行的,但它们是类型安全的。

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,并且将丢弃它们的返回值并收集垃圾。