不同之处在于flatMap将返回一个可迭代的数据展平到列表中。 但是在Akka文档中,map和flatMap似乎做了不同的事情?
http://akka.io/docs/akka/1.1/scala/futures.html
它说“通常情况下这很有效,因为这意味着运行快速功能的开销非常小。如果该功能有可能需要花费很多时间来处理它,那么这可能会更好同时完成,为此我们使用flatMap:“
val f1 = Future {
"Hello" + "World"
}
val f2 = f1 flatMap {x =>
Future(x.length)
}
val result = f2.get()
有人可以解释Akka期货中地图和flatMap之间的区别吗?
答案 0 :(得分:60)
在“普通”Scala中(如你所说),map和flatMap与列表无关(例如选中Option)。
Alexey给了你正确的答案。现在,如果你想知道为什么我们需要两者,它在编写期货时允许使用漂亮的for
语法。给出类似的东西:
val future3 = for( x <- future1;
y <- future2 ) yield ( x + y )
编译器将其重写为:
val future3 = future1.flatMap( x => future2.map( y => x+y ) )
如果您遵循方法签名,您应该看到该表达式将返回Future[A]
类型的内容。
假设现在只使用了map,编译器可以做类似的事情:
val future3 = future1.map( x => future2.map( y => x+y ) )
但是,结果应该是Future[Future[A]]
类型。这就是你需要压扁它的原因。
要了解背后的概念,这是我读过的最好的介绍之一:
http://www.codecommit.com/blog/ruby/monads-are-not-metaphors
答案 1 :(得分:35)
有人可以解释Akka期货中地图和flatMap之间的区别吗?
类型,基本上:
flatMap[A](f: T => Future[A]): Future[A]
map[A](f: T => A): Future[A]
答案 2 :(得分:1)
我在这里粘贴了两种方法的实现。 英语术语的差异如下 并将函数的结果作为新的未来返回
/** Creates a new future by applying a function to the successful result of
* this future. If this future is completed with an exception then the new
* future will also contain this exception.
*
* $forComprehensionExamples
*/
def map[S](f: T => S)(implicit executor: ExecutionContext): Future[S] = { // transform(f, identity)
val p = Promise[S]()
onComplete { v => p complete (v map f) }
p.future
}
/** Creates a new future by applying a function to the successful result of
* this future, and returns the result of the function as the new future.
* If this future is completed with an exception then the new future will
* also contain this exception.
*
* $forComprehensionExamples
*/
def flatMap[S](f: T => Future[S])(implicit executor: ExecutionContext): Future[S] = {
import impl.Promise.DefaultPromise
val p = new DefaultPromise[S]()
onComplete {
case f: Failure[_] => p complete f.asInstanceOf[Failure[S]]
case Success(v) => try f(v) match {
// If possible, link DefaultPromises to avoid space leaks
case dp: DefaultPromise[_] => dp.asInstanceOf[DefaultPromise[S]].linkRootOf(p)
case fut => fut.onComplete(p.complete)(internalExecutor)
} catch { case NonFatal(t) => p failure t }
}
p.future
}
从实现开始,不同之处在于,当promise完成时,flatMap实际上会调用带有结果的函数。
case Success(v) => try f(v) match
阅读一篇好文章:http // danielwestheide.com / blog / 2013/01/16 / the-neophytes-guide-to-scala-part-9-promises-and-futures-in-practice.html < / p>