【问题标题】:How to resolve a list of futures in Scala如何在 Scala 中解析期货列表
【发布时间】:2013-11-29 12:17:44
【问题描述】:

我有一个返回 Future 的调用。 但是,我需要打 n 个电话,所以我会得到 n 个期货。我想知道在继续之前如何让期货全部解决(不阻塞服务器)

例如,

while(counter < numCalls){
    val future = call(counter)
    future.map{  x =>
        //do stuff
    }
    counter += 1 
}

//Now I want to execute code here after ALL the futures are resolved without 
//blocking the server

【问题讨论】:

  • 您可以将 for ... yield 与期货结合使用

标签: scala playframework-2.0 future


【解决方案1】:

您可以使用Future.sequence(futureList)List[Future[X]] 转换为Future[List[X]]。由于后者只是一个简单的Future,您可以在Await.ready 或类似助手的帮助下等待它完成。

因此,您必须保留一份您生成的期货的清单。比如:

val futures = new ListBuffer[Future[X]]
while(counter < numCalls) {
    val future = call(counter)
    futures += future
    future.map { x =>
        //do stuff
    }
    counter += 1 
}
val f = Future.sequence(futures.toList)
Await.ready(f, Duration.Inf)

你也可以写成:

val futures = (1 to numCalls).map(counter => {
    f = call(counter)
    f.map(x => ...)
    f
})
Await.ready(Future.sequence(futures), Duration.Inf)

【讨论】:

  • 除非你调用 Await.ready 否则你会阻塞 - 出于说明目的,这很好,但你不应该阻塞你的生产代码 - 如果你真的可以避免它.. . 你几乎总是可以避免它。
  • 对不起,我很着急,贴错了行。我的意思是:val f = Future.sequence(futures.toList)。我最终使用了 f.map 来等待它解决
【解决方案2】:

更多功能:

val futures = for {
  c <- 0 until 10
   } yield {
    val f = call(c) 
    f onSuccess {
      case x =>
      // Do your future stuff with x
    }
    f
  }
Future.sequence(futures)

【讨论】:

  • 这比接受的答案更实用?
【解决方案3】:

我认为你想在期货完成后做一些事情,例如。回调,而不阻塞原始呼叫?然后你应该这样做:

val futures = for (...) yield {
  future {
  ...
  }
}

val f = Future sequence futures.toList

f onComplete {
  case Success(results) => for (result <- results) doSomething(result)
  case Failure(t) => println("An error has occured: " + t.getMessage)
}

http://docs.scala-lang.org/overviews/core/futures.html

因此,您不会因 await 调用而阻塞,但您仍会等待所有 Futures 完成,然后对所有结果执行某些操作。关键方面是使用 Future.sequence 将许多期货连接在一起,然后使用回调对结果进行操作。

【讨论】:

    猜你喜欢
    • 2014-12-30
    • 2021-03-02
    • 2016-04-05
    • 1970-01-01
    • 2017-03-26
    • 2019-11-04
    • 2021-01-01
    • 1970-01-01
    相关资源
    最近更新 更多