Future.zip和Future.zipWith实现中的细微差别。为什么?

时间:2018-08-22 14:05:45

标签: scala

让我们考虑以下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}}(当前线程)。这种理解正确吗?

1 个答案:

答案 0 :(得分:2)

f的应用是通过提供的ExecutionContext完成的,并且internalExecutor用于执行展平操作。规则基本上是:当用户提供逻辑时,该逻辑在用户提供的ExecutionContext上执行。

您可以想象将zipWith实现为this.zip(that).map(f.tupled)或将zip实现为zipWith(Tuple2.apply)(internalExecutor)