我想用不同的参数调用func()
,并且应该并行调用此函数。
for(i <- 0 to count) {
Future {
for(j <- 0 to n_count) {
Future {
func(a,b, c(i), d(j))
}
}
}
}
这是正确的方法吗?
我的功能也没有返回任何东西。那么如何知道执行是并行运行还是创建了多少线程。请在Scala中提供此类方案的完整代码。
答案 0 :(得分:1)
这非常简单,因为这个原因,scala会为您提供Future.sequence
和Future.traverse
通过将M[Future[T]]
类型的任何集合转换为Future[M[T]]
的集合,它们大致以相同的方式工作,但它们的使用方式不同。
val actions = List(Future(5), Future(6), Future(7))
val executed = Future.sequence(actions) map (l => println(l.mkString()) // 5, 6 ,7
现在Future.traverse
在语义上是不同的,因为您为它提供了一个M[A]
或一组元素,然后是一个将这些元素转换为未来的函数。例如:
val userIds = List(1, 2, 3, 4 , 5)
// let's pretend this calls an SQL DB
def userById(id: Int): Future[Option[User]]
Future.traverse(userIds)(id => userById(id))
就执行语义而言,两个构造都并行执行所有期货,如果任何期货失败则失败。没有保证期货按顺序执行。
关闭主题,但幸运的是,一次编写一个&#34;一次逻辑非常容易
你自己。这是通过从元素&#34;内部&#34;移动产生Future
的函数来实现的。 for block。 Scala中的期货总是在已经开始的状态下创建,这使得它们更难以推理。
def sequencedTraverse[
A,
B,
M[X] <: TraversableOnce[X]
](in: M[A])(fn: A => Future[B])(implicit
executor: ExecutionContextExecutor,
cbf: CanBuildFrom[M[A], B, M[B]]
): Future[M[B]] = {
in.foldLeft(Future.successful(cbf(in))) { (fr, a) =>
for (r <- fr; b <- fn(a)) yield r += b
}.map(_.result())
}
答案 1 :(得分:0)
基于@flavian的优秀答案:
scala> val a = "a"
a: String = a
scala> val b = "b"
b: String = b
scala> val c = List("x","y","z")
c: List[String] = List(x, y, z)
scala> val d = List("u","v","w")
d: List[String] = List(u, v, w)
scala> def func(a: String, b: String, c: String, d: String) = a + b + c + d
func: (a: String, b: String, c: String, d: String)String
scala> val futures = for{i <- c; j <- d} yield Future(func(a,b,i,j))
futures: List[scala.concurrent.Future[String]] = List(Future(Success(abxu)), Future(Success(abxv)), Future(Success(abxw)), Future(Success(abyu)), Future(Success(abyv)), Future(Success(abyw)), Future(Success(abzu)), Future(Success(abzv)), Future(Success(abzw)))
scala> Future.sequence(futures)
res0: scala.concurrent.Future[List[String]] = Future(<not completed>)
scala> res0
res1: scala.concurrent.Future[List[String]] = Future(Success(List(abxu, abxv, abxw, abyu, abyv, abyw, abzu, abzv, abzw)))