2014-01-21 45 views
7

当我制作future或应用方法如onSuccessmap时,我可以为它们指定ExecutionContext。Scala:用于将来理解的ExecutionContext

例如,

val f = future { 
    // code 
} executionContext 

f.map(someFunction)(executionContext) 

f onSuccess { 
    // code 
} executionContext 

但是,如果我用一个换理解未来的,我怎么能为yield部分指定的ExecutionContext?

for { 
    f <- future1 
    g <- future2 
} yield { 
    // code to be executed after future1 onSuccess and future2 onSuccess 
    // What ExecutionContext runs this code? 
} // (executionContext) here does not work 

而且,如果没有指定,ExecutionContext在yield中运行代码?


编辑

确定。感谢答案,我找到了一些东西。
如果我没有定义或导入隐含的ExecutionContext(如Implicits.global), 的换理解不编译。这意味着,for-comprehension使用隐式的ExecutionContext。

然后,我该如何使用不含隐式ExecutionContext的理解,即如何指定?

+0

请参阅我的回答,了解为什么如果您没有指定“隐式”,for'comprehensions将无法编译。 –

+0

@flavian在简单的情况下,这是有效的。但是如果有两个ExecutionContext用于理解,我该如何指定?它会显示错误,如“含糊的隐含值”。我可以阻止每次我定义或导入隐式vals或defs&for-comprehension,但有没有另一种方式? – Naetmul

+0

只是要绝对确定 - 你的意思是用多个生成器(在这种情况下,flavian的答案是有效的)还是多个相应的for-comprehensions一个'for for'-理解? –

回答

8

ExecutionContext参数实际上是implicit。这意味着您可以:

import scala.concurrent.ExecutionContext 

implicit val context = ExecutionContext.fromExecutor(//etc) 
for { 
    f <- future1 
    g <- future2 
} yield { 
    // code to be executed after future1 onSuccess and future2 onSuccess 
    // What ExecutionContext runs this code?: the one above. 
} 

您还有一个默认值,即scala.concurrent.ExecutionContext.Implicits.global。 这与运行机器上的处理器具有尽可能多的线程。

默认情况下,它不会被所有期货使用,您仍然需要导入它。

更新:如果你真的想specifiy,尽管它不建议,您可以解开的for yield

val combined = futureA.flatMap(x => futureB)(context) 
+0

如果在作用域中有两个隐式ExecutionContext并且您需要选择一个呢? – kostya

+1

@kostya你可以使用像这样的选择性别名:'import com.bla.bla。{contextToDiscard => _,_}'。如果它是导致问题的软件包导入,那么只会将其中一个导入范围。另一种方法是将导入执行者的进口移至较低的范围。 – flavian

1

由于for内涵是“映射”到map/flatMap操作和ExecutionContext参数这些都是隐含的,我想你可以尝试在本地范围内添加一个implicit val

implicit val myContext:ExecutionContext = ...

我不相信有一个“默认”隐含ExecutionContext,但最常用的是ExecutionContext.Implicits.global