6

免责声明:下面的代码片段与正在进行的 Coursera 课程之一有关。让我们认为它只是为了学习目的而发布的,不应该用于提交作为家庭作业的解决方案。

正如下面的评论所述,我们需要将 Future 列表转换为列表的单个 Future。不仅如此,如果至少有一个输入期货失败,则生成的未来应该失败。

我遇到了以下实现,我不完全理解。

/** Given a list of futures `fs`, returns the future holding the list of values of all the futures from `fs`.
 *  The returned future is completed only once all of the futures in `fs` have been completed.
 *  The values in the list are in the same order as corresponding futures `fs`.
 *  If any of the futures `fs` fails, the resulting future also fails.
 */
def all[T](fs: List[Future[T]]): Future[List[T]] = 
             fs.foldRight(Future(Nil:List[T]))((f, fs2) =>
  for {
    x <- f
    xs <- fs2
  } yield (x::xs))

特别是,我不明白其中的以下内容:

  1. Future[T] -> T转变发生在哪里?它看起来xs <- fs2是我们唯一接触 initial 的地方Futures,每种xs类型都应该是Future[T](但不知何故它变成了 just T)。
  2. 故障如何处理?当其中一个输入失败时,结果Future对象似乎确实失败了Futures
4

2 回答 2

6

1) 说 f 是 a Future[T],然后写

for {
 t <- f
}  yield List(t)

将Future f 的结果存储在t 中——因此t 的类型为T。yield 将其变成List[T],整个for-comprehension 的类型最终为Future[List[T]]。所以理解是你从你的 T 中提取你的 T Futures,对它们做一些事情,然后把它们放回 Future (好吧,我在这里简化了一点)。

相当于

f.map(t => List(t))

2) 如果你的 Future f 包含一个失败,那么 for-comprehension 将只返回这个失败的 Future 而不是执行 yield。

作为一般说明,Scala 中的 for-comprehension 只是可以用map, flatMap, filter, foreach.

于 2013-12-01T01:27:38.433 回答
2

我是说英语的右撇子,所以通常我会向左折叠,但折叠的每一步看起来像:

Fn flatMap ((x: T) => Fs map (xs => x :: xs))

你的价值是x

该功能适用​​于成功,这解释了为什么失败会让你感到寒冷:

scala> timed(Await.ready(all(List(Future{Thread sleep 5*1000; 1},Future(2),Future{Thread sleep 10*1000; 3})), Duration.Inf))
res0: (Long, scala.concurrent.Awaitable[List[Int]]) = (10002419021,scala.concurrent.impl.Promise$DefaultPromise@2a8025a0)

scala> timed(Await.ready(all(List(Future{Thread sleep 5*1000; 1},Future(???),Future{Thread sleep 10*1000; 3})), Duration.Inf))
res1: (Long, scala.concurrent.Awaitable[List[Int]]) = (5000880298,scala.concurrent.impl.Promise$DefaultPromise@3750d517)

请注意,失败的版本会短路。

有关这两个信息,请参阅 ScalaDoc for flatMap。

编辑:我说话很谨慎,因为它是 Coursera 的工作,但更简单地说,这个要求不满足:“返回的未来只有在所有的期货都完成后才fs完成。”

于 2013-12-01T02:38:54.030 回答