Why does this list-of-futures to future-of-list transformation compile and work?

a 夏天 提交于 2019-12-05 08:03:11

1) Say f is a Future[T], then writing

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

will store the result of the Future f in t - therefor t is of type T. The yield turns it into a List[T], and the type of the whole for-comprehension ends up being Future[List[T]]. So the for-comprehension is where you extract your Ts from your Futures, do something with them, and put them back in a Future (OK, I'm simplifying a little bit here).

It's equivalent to

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

2) If your Future f contains a Failure, then the for-comprehension will just return this failed Future instead of executing the yield.

As a general note, for-comprehension in Scala is just sugar that can be rewritten with map, flatMap, filter, foreach.

I'm an English-speaking right-hander, so normally I foldLeft, but each step of the fold looks like:

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

Your value is x.

The function is applied on success, which explains why a failure stops you cold:

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)

Notice that the failing version short-circuits.

See the ScalaDoc for flatMap for both bits of information.

Edit: I was speaking cautiously because it is Coursera work, but more plainly, this requirement is not met: "The returned future is completed only once all of the futures in fs have been completed."

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!