合并两个Slick Futures,然后一起执行

时间:2015-06-26 14:41:16

标签: scala slick slick-3.0

我已编写此代码,并且我正在尝试合并从单独的SQL操作中获得的两个期货。

package com.example

import tables._
import scala.concurrent.{Future, Await}
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.duration.Duration
import slick.backend.DatabasePublisher
import slick.driver.H2Driver.api._

object Hello {
  def main(args: Array[String]): Unit = {
    val db = Database.forConfig("h2mem1")
    try {
      val people = TableQuery[Persons]
      val setupAction : DBIO[Unit] = DBIO.seq(
        people.schema.create
        )
      val setupFuture : Future[Unit] = db.run(setupAction)

      val populateAction: DBIO[Option[Int]] = people ++= Seq(
          (1, "test1", "user1"),
          (2, "test2", "user2"),
          (3, "test3", "user3"),
          (4, "test4", "user4")
        )

      val populateFuture : Future[Option[Int]] = db.run(populateAction)

      val combinedFuture : Future[Option[Int]] = setupFuture >> populateFuture

      val r = combinedFuture.flatMap { results =>
        results.foreach(x => println(s"Number of rows inserted $x"))
      }
      Await.result(r, Duration.Inf)
    } 
    finally db.close
  }
}

但是当我尝试编译此代码时出现错误

[error] /Users/abhi/ScalaProjects/SlickTest2/src/main/scala/Hello.scala:29: 
value >> is not a member of scala.concurrent.Future[Unit]
[error]       val combinedFuture : Future[Option[Int]] = setupFuture >>
populateFuture
[error]                                                              ^
[error] one error found
[error] (compile:compileIncremental) Compilation failed

相同的代码可以工作,如果我将populateFuture嵌套在setupFuture的map函数中。但是我不想编写嵌套代码,因为一旦有更多的步骤,它就会变得非常混乱。

因此,我需要一种方法将所有期货合并为一个未来,然后执行它。

编辑::我也试过结合这两个动作

  val combinedAction = setupAction.andThen(populateAction)

  val fut1 = combinedAction.map{result =>
    result.foreach{x =>println(s"number or rows inserted $x")}
  }
  Await.result(fut1, Duration.Inf)

但收到错误

/Users/abhi/ScalaProjects/SlickTest/src/main/scala/com/example/Hello.scala:31: type mismatch;
[error]  found   : scala.concurrent.Future[Option[Int]]
[error]  required: PartialFunction[scala.util.Try[Unit],?]
[error]       val combinedAction = setupAction.andThen(populateAction)
[error]                                                ^
[error] one error found
[error] (compile:compileIncremental) Compilation failed
[error] Total time: 3 s, completed Jun 26, 2015 3:50:51 PM
Mohitas-MBP:SlickTest abhi$ 

1 个答案:

答案 0 :(得分:2)

根据http://slick.typesafe.com/doc/3.0.0/api/index.html#slick.dbio.DBIOAction,您需要andThen()

val combinedAction = setupAction.andThen(populateAction)
val results = db.run(combinedAction)

populateAction只会在setupAction成功完成后运行。这对你的情况至关重要,因为光滑是完全无阻塞的。您现在拥有的代码将在运行时导致问题。代码中的两个操作都将同时异步运行。无法确定首先执行的操作。但由于populateAction取决于setupAction,因此您必须先确保执行setupAction。因此,请使用andThen