使用 Scala Futures 按顺序执行依赖项

Executing dependencies in order using Scala Futures

我有一个任务运行ner如下

package taskman

import scala.concurrent.{Await, Future}
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.duration._

final class Task private (
    desc: String,
    dependencies: Seq[Task] = Seq.empty[Task],
    body: => Unit
) {

  def run(): Future[Unit] = Future {
//    println(s"Executing dependencies for $desc")
    Future
      .sequence(dependencies.map(_.run()))
      .map { _ => body }
  }
}

object Task {
  def task(desc: String, dependencies: Seq[Task] = List.empty[Task])(
      body: => Unit
  ): Task =
    new Task(desc, dependencies, body)
}

object taskTest extends App {
  import Task._

  val boilWater = task("Boil water") {
    println("Boiling water ")
  }

  val boilMilk = task("Boil milk") {
    println("Boiling milk")
  }

  val mixWaterAndMilk =
    task("Mix milk and water", Seq(boilWater, boilMilk)) {
      println("Mixing milk and water")
    }

  val addCoffeePowder = task("Add coffee powder", Seq(mixWaterAndMilk)) {
    println("Adding coffee powder")
  }

  val addSugar = task("Add sugar", Seq(addCoffeePowder)) {
    println("Adding sugar")
  }

  val makeCoffee = task("Make coffee", Seq(addSugar)) {
    println("Coffee is ready to serve")
  }

  Await.result(makeCoffee.run, 10.seconds)
}

我希望并行 运行 的依赖项,完成后执行正文。但是我总是按错误的顺序得到这个。

预期顺序如下

开水 煮牛奶 混合牛奶和水 添加咖啡粉 加糖 咖啡已准备就绪

煮牛奶和水可以按任何顺序进行,但其余的事情要按顺序进行。我在 Future.sequence.map {} 上执行正文,但顺序仍然不正确。这段代码肯定有问题,但我无法弄清楚。

问题是 run 中的虚假额外 Future

def run(): Future[Unit] = Future { // <-- Not required
  Future
    .sequence(dependencies.map(_.run()))
    .map { _ => body }
}

删除它可以解决问题:

def run(): Future[Unit] = 
  Future
    .sequence(dependencies.map(_.run()))
    .map { _ => body }