Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/apache-kafka/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Play/Scala:并行进行未知数量的I/O调用,等待结果_Scala_Concurrency_Playframework 2.0 - Fatal编程技术网

Play/Scala:并行进行未知数量的I/O调用,等待结果

Play/Scala:并行进行未知数量的I/O调用,等待结果,scala,concurrency,playframework-2.0,Scala,Concurrency,Playframework 2.0,所以,我读了一篇关于平行理解的文章。他给出了以下代码示例: // Make 3 parallel async calls val fooFuture = WS.url("http://foo.com").get() val barFuture = WS.url("http://bar.com").get() val bazFuture = WS.url("http://baz.com").get() for { foo <- fooFuture bar <- barFutu

所以,我读了一篇关于平行理解的文章。他给出了以下代码示例:

// Make 3 parallel async calls
val fooFuture = WS.url("http://foo.com").get()
val barFuture = WS.url("http://bar.com").get()
val bazFuture = WS.url("http://baz.com").get()

for {
  foo <- fooFuture
  bar <- barFuture
  baz <- bazFuture
} yield {
  // Build a Result using foo, bar, and baz
  Ok(...)
} 
电话号码为:

def callOne(param: String): Future[Boolean] = {
  // do something and return the Future with a true/false value
  Future(true)
}

def callTwo(param: String): Future[Boolean] = {
  // do something and return the Future with a true/false value
  Future(false)
}
所以,我的问题是,我应该如何对WS调用(或数据库查询)序列的结果做出反应,以获得收益

我已经给出了两个调用的示例,但我希望相同的代码能够并行处理1到多个调用,并在yield中收集结果,以便最终继续做其他事情

重要提示:所有呼叫应并行执行,最快的呼叫将在慢速呼叫之前完成,而不考虑它们的触发顺序。

很可能就是您想要的

用法示例:

val futures = List(WS.url("http://foo.com").get(), WS.url("http://bar.com").get())
Future.sequence(futures) # => Transforms a Seq[Future[_]] to Future[Seq[_]]
在输入序列中的所有期货完成之前,future.sequence的未来收益将不会完成

奖金:

如果您的未来是异构类型的,并且您需要保留该类型,那么可以使用Hlist。我已经编写了以下代码段,它将获取一个HL未来列表,并将其转换为包含一个HL已解析值列表的未来:

import shapeless._
import scala.concurrent.{ExecutionContext,Future}

object FutureHelpers {
  object FutureReducer extends Poly2 {
    import scala.concurrent.ExecutionContext.Implicits.global
    implicit def f[A, B <: HList] = at[Future[A], Future[B]] { (f, resultFuture) =>
      for {
        result <- resultFuture
        value <- f
      } yield value :: result
    }
  }

  // Like Future.sequence, but for HList
  // hsequence(Future { 1 } :: Future { "string" } :: HNil)
  // => Future { 1 :: "string" :: HNil }
  def hsequence[T <: HList](hlist: T)(implicit
    executor: ExecutionContext,
    folder: RightFolder[T, Future[HNil], FutureReducer.type]) = {
    hlist.foldRight(Future.successful[HNil](HNil))(FutureReducer)
  }
}
导入无形状_
导入scala.concurrent.{ExecutionContext,Future}
对象未来助手{
对象未来2{
导入scala.concurrent.ExecutionContext.Implicits.global
隐式定义f[A,B
为了{

结果看起来像是我正在寻找的,但是,在我等待全部完成之前,如何动态地填充
未来
?如果您有一个url:Seq[String |,url映射(WS.url).好的,所以我测试了Future.sequence一点,但它们是按顺序执行的,1,2,3…等等,我真的在寻找一个解决方案,一次触发所有事件,然后等待所有事件的结束。你正在寻找的正是Future.sequence所做的。换句话说,一旦你实例化它们,你的未来就会被安排好。所以,如果您实例化一个未来列表,它们将被同时调度(在ExecutionContext允许的范围内;您可能需要根据您的设备调整executor以获得更高的并行性,因为它默认为机器上2倍的内核).Future.sequence将只等待列表中的每个未来,然后向您提供结果列表(与提供的未来列表的顺序相同)。
import shapeless._
import scala.concurrent.{ExecutionContext,Future}

object FutureHelpers {
  object FutureReducer extends Poly2 {
    import scala.concurrent.ExecutionContext.Implicits.global
    implicit def f[A, B <: HList] = at[Future[A], Future[B]] { (f, resultFuture) =>
      for {
        result <- resultFuture
        value <- f
      } yield value :: result
    }
  }

  // Like Future.sequence, but for HList
  // hsequence(Future { 1 } :: Future { "string" } :: HNil)
  // => Future { 1 :: "string" :: HNil }
  def hsequence[T <: HList](hlist: T)(implicit
    executor: ExecutionContext,
    folder: RightFolder[T, Future[HNil], FutureReducer.type]) = {
    hlist.foldRight(Future.successful[HNil](HNil))(FutureReducer)
  }
}