等待所有Scala期货完成

时间:2015-06-05 21:17:05

标签: scala future scrimage

我有一个像这样的理解使用支持并发操作的图像库https://github.com/sksamuel/scrimage

for (
      file <- myDirectory.listFiles;
      image <- AsyncImage(file);
      scaled <- image.scale(0.5)
      // possibly more ops here? 
    )
    {
      scaled.writer(Format.PNG).write(new File(dirOutput + file.getName))
    }

这里是write()的定义:

def write(out: OutputStream)(implicit executionContext: ExecutionContext): Future[Unit] = Future {
  writer.write(out)
}

我想要做的是等待我的目录中的所有图像在程序关闭之前完成大小调整。从我从SO上的其他帖子中收集的内容来看,基本上将所有这些期货都填入了期货列表中并使用Await来完成...可以有人帮助我吗?

1 个答案:

答案 0 :(得分:1)

您遇到的问题是您混合了两种不同的一元理解,即listFiles返回List[File]image.scale返回Future[Image]。虽然两者都可以在 for-comprehension 中使用,但它们不能混合使用。此外,image <- AsyncImage(file)应该是一个赋值,因为它只返回一个实例:

// start the scaling operations (this is a List comprehension)
val scaleOps: List[Future[Unit]] = for {
  file <- myDirectory.listFiles
  image = AsyncImage(file)

  // Now transform the image into a Future[Unit] with a nested Future comprehension
  ops = for {
    scaled <- image.scale(0.5)
    written <- scaled.writer(Format.PNG).write(new File(dirOutput + file.getName)) 
  } yield { written }
} yield { ops }

// collect and await the results
Await.result(Future.sequence(scaleOps), 10 minutes)

在外部理解<-中始终生成List中的项目,yield返回最终列表。

在内部理解<-中始终生成Future的值,允许您将其用作生成Future的另一个调用的输入,从而生成Future[Unit]超出image