【问题标题】:Scala Promise ClarificationScala 承诺澄清
【发布时间】:2015-01-31 03:25:41
【问题描述】:

快速提问,如果在 Scala 中,你在哪里可以实现这样的承诺;

 val successful = Promise[List[T]]()     //Create a promise which will be returning the results
 successful.success(Nil)   

这不会完成承诺,因此不允许您进一步写入承诺吗?哪个也会触发 Promise onComplete 回调?

我问的原因是我试图理解以下代码,并且我试图理解为什么在未来的计算甚至开始之前用 Nil 初始化承诺。

def all[T](fs: List[Future[T]]): Future[List[T]] = {
  val successful = Promise[List[T]]()     //Create a promise which will be returning the results
  successful.success(Nil)                 //Initialize the profile
  fs.foldRight(successful.future) {       //Create the Aggregate for the fold right which will be an empty future
    //for each element extract the element from the future and append to our aggregate
    //f -> Future[T] acc -> Future[List[T]]
    (f, acc) => for { x <- f; xs <- acc } yield x :: xs
  }
}

大声思考我会说完成承诺的原因是没有附加callbacsk,因此我们不在乎它何时成功。如果是这样,使用 Promise 的唯一原因是利用它的未来。那么,在不使用我们实际上不需要的承诺的情况下,他们不是更简单/更清洁的方式来定义未来吗?

【问题讨论】:

  • 在这种情况下,需要它来处理fs 为空的情况。
  • 所以假设 fs 不为空。由于之前的成功已经设置了 foldright 会触发 promise 上的 onComplete 回调吗?
  • 没有调用“onComplete”来注册回调。
  • Empty 和 null 不是一回事。 fs 是一个列表,如果你在一个空列表上调用 foldRight,你会得到一个例外。在这种情况下,没有 onComplete 回调,只有返回新期货的组合器。

标签: scala


【解决方案1】:

是的,一个承诺只完成一次(我不确定你所说的“onComplete 回调”是什么意思,我在标准库Promise docs 中没有看到这样的东西)。当然,即使 promise 已经完成,promise 的 future 也是可用的并且可以按预期工作。这看起来是使用Future.successful(Nil) 作为foldRight 的初始元素的一种过于复杂的方式。

【讨论】:

  • sorry by onComplete 我指的是 promise 的 onSuccess 方法,它不在代码中的任何位置,但它只是一个假设性问题。因此,为了确保我正确理解您,success.success(Nil) 初始化了未来:Future[List[T]] 到 Nil,它基本上将在 foldRight 中使用。反正有没有更优雅的方式写下面的代码?
  • 您可以将代码编写为fs.foldRight(Future.successful(List[T]())) { ...。更优雅的是,如果您使用 Scalaz 并且在范围内有一个 implicit ExecutionContext,那么整个函数就是 fs.sequence(至少,我认为 scalaz 在某处带有一个 Applicative[Future])。
猜你喜欢
  • 2013-09-28
  • 2016-11-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多