合并两个 Slick Futures 然后一起执行
Combine Two Slick Futures and then execute them together
我写了这段代码,我正在尝试合并从单独的 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 函数中。但是我不想写嵌套的代码,因为一旦有更多的步骤要做,它会变得很乱。
所以我需要一种方法将所有 future 组合成一个 future 然后执行它。
编辑::我也试过结合这两个动作
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$
根据 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
成功完成后 运行。这对您的情况至关重要,因为 slick 是完全无阻塞的。您现在拥有的代码将在 运行 时引起问题。您代码中的两个操作将同时异步 运行。无法确定先执行哪个操作。但是因为populateAction
依赖于setupAction
,你必须确保setupAction
先执行。因此使用 andThen
.
我写了这段代码,我正在尝试合并从单独的 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 函数中。但是我不想写嵌套的代码,因为一旦有更多的步骤要做,它会变得很乱。
所以我需要一种方法将所有 future 组合成一个 future 然后执行它。
编辑::我也试过结合这两个动作
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$
根据 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
成功完成后 运行。这对您的情况至关重要,因为 slick 是完全无阻塞的。您现在拥有的代码将在 运行 时引起问题。您代码中的两个操作将同时异步 运行。无法确定先执行哪个操作。但是因为populateAction
依赖于setupAction
,你必须确保setupAction
先执行。因此使用 andThen
.