让我们考虑以下scala.concurrent.Future.scala
的摘录:
def zip[U](that: Future[U]): Future[(T, U)] = {
implicit val ec = internalExecutor
flatMap { r1 => that.map(r2 => (r1, r2)) }
}
def zipWith[U, R](that: Future[U])(f: (T, U) => R)(implicit executor: ExecutionContext): Future[R] =
flatMap(r1 => that.map(r2 => f(r1, r2)))(internalExecutor)
除了f
情况下函数zipWith
的应用外,它看起来没有太大区别。对我来说很有趣,为什么internalExecutor
(仅委托给当前线程)在zip
中声明为隐式值,并因此在基础map
和{{1}中使用}调用,但仅在flatMap
内部的flatMap
调用中明确使用?
据我的理解,zipWith
函数的执行可能涉及某些阻塞或密集计算,这超出了Scala库的控制范围,因此用户应为其提供另一个执行上下文,以免偶尔阻塞{ {1}}(当前线程)。这种理解正确吗?
答案 0 :(得分:2)
f
的应用是通过提供的ExecutionContext
完成的,并且internalExecutor
用于执行展平操作。规则基本上是:当用户提供逻辑时,该逻辑在用户提供的ExecutionContext
上执行。
您可以想象将zipWith
实现为this.zip(that).map(f.tupled)
或将zip
实现为zipWith(Tuple2.apply)(internalExecutor)
。