【问题标题】:Running future n times运行未来 n 次
【发布时间】:2013-10-08 13:22:11
【问题描述】:

我想运行我未来的调用 n 次,例如 5。未来的“执行”将需要一些时间,我只想在前一个完成时调用新的。比如:

def fun(times: Int): Future[AnyRef] = {
   def _fun(times: Int) = {
      createFuture()
   }

    (1 to times).foldLeft(_fun)((a,b) => {
      println(s"Fun: $b of $times")
      a.flatMap(_ => _fun)
    })
}

所以我想一一调用“_fun”函数n次。 “createFuture()”需要一些时间,所以在前一个未来完成之前不应再次调用“_fun”。另外,我想创建一个非阻塞解决方案。目前,此代码无需等待先前的未来结束即可执行。

任何想法如何使它工作?

感谢您的回答!

【问题讨论】:

  • 你希望你的返回类型代表什么?它是否需要以某种方式聚合链接的未来调用的结果?

标签: scala nonblocking future


【解决方案1】:

如果不了解您究竟希望最终的未来返回什么(我将只返回最后完成的未来的结果),您可以尝试这样的事情:

def fun(times: Int): Future[AnyRef] = {
  val prom = Promise[AnyRef]()
  def _fun(t: Int) {

    val fut = createFuture()  
    fut onComplete {
      case Failure(ex) => prom.failure(ex)
      case Success(result) if t >= times => prom.success(result)
      case Success(result) => _fun(t + 1)
    }

  }
  _fun(1)

  prom.future
}

这是一种递归解决方案,它将在完成时将期货链接在一起,当达到最大次数时停止链接。这段代码并不完美,但肯定传达了一种可能的解决方案,以确保在前一个 future 成功完成之前不会触发连续的 future。

【讨论】:

  • 抱歉,忘记指定我想返回最后一个未来或它们的序列,实际上并不那么重要。您的解决方案按我的预期工作,谢谢。这对于临时解决方案非常有用,稍后会考虑让它更漂亮:)
【解决方案2】:

我认为如果你使用 flatMap 使其递归会更好。

假设您将 createFuture 定义为:

def createFuture() = Future( println("Create future"))

我们可以创建一个函数来组合 createFuture 的结果:

   def compose(f: () => Future[Unit])(b: Future[Unit]) = b.flatMap(_ => f())

然后你可以将乐趣定义为:

 def fun(n : Int) = {
     def nTimes(n : Int, f : Future[Unit] => Future[Unit], acc : Future[Unit]) = if (n == 0) acc else nTimes(n-1,f,f(acc))
     nTimes(n,compose(createFuture),Future())
 }

【讨论】:

    猜你喜欢
    • 2015-05-15
    • 2019-05-18
    • 1970-01-01
    • 1970-01-01
    • 2020-07-14
    • 2021-05-22
    • 2015-07-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多