Future.zip和Future.zip的实现略有不同。为什么? 让我们考虑下面的代码: 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)
除了函数Future.zip和Future.zip的实现略有不同。为什么? 让我们考虑下面的代码: 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),scala,Scala,除了函数f在zipWith案例中的应用外,它似乎没有太大区别。我感兴趣的是,为什么internalExecutor(它只是委托给当前线程)在zip中声明为隐式值,并因此在底层map和flatMap调用中使用,但仅在zipWith中的flatMap调用中显式使用 经过一番思考后,我了解到,f函数执行可能会涉及一些超出Scala库控制的阻塞或密集计算,因此用户应该为它提供另一个执行上下文,以避免偶尔阻塞internalExecutor(当前线程)。这种理解正确吗?应用f是通过提供的Execution
f
在zipWith
案例中的应用外,它似乎没有太大区别。我感兴趣的是,为什么internalExecutor
(它只是委托给当前线程)在zip
中声明为隐式值,并因此在底层map
和flatMap
调用中使用,但仅在zipWith
中的flatMap
调用中显式使用
经过一番思考后,我了解到,
f
函数执行可能会涉及一些超出Scala库控制的阻塞或密集计算,因此用户应该为它提供另一个执行上下文,以避免偶尔阻塞internalExecutor
(当前线程)。这种理解正确吗?应用f
是通过提供的ExecutionContext
完成的,而internalExecutor
用于执行展平操作。规则基本上是:当用户提供逻辑时,该逻辑在用户提供的ExecutionContext
上执行
您可以想象
zipWith
被实现为this.zip(that).map(f.tuple)
,或者zip
被实现为zipWith(Tuple2.apply)(internalExecutor)
。。。这两种实现都将隐式地忽略任何其他可用的ExecutionContext
,并将使用ExecutionContext
,它用于此未来的。此internalExecutor
是一个特殊的执行器,应该用于所有应隐藏在不希望这些内部回调污染其应用程序关键执行上下文的开发人员。这就是说,这个
和那个
未来
的执行将在应用程序的执行上下文
中发生(以范围中可用的为准)但是所有的回调都将在internalExecutor
中执行。我还发现了您的“几篇文章描述了scala 2.12.x中scala.concurrent.future的演变”,其中介绍了这两种方法以及其他一些内容。谢谢。