我需要找回在Future的onSuccess块中更改的变量。这是我的示例代码。
def futureFunction(arg:Any):Any = {
implicit val timeout = Timeout(10 seconds)
var ret:Any = None
val f: Future[Any] = someActor ? arg
f.onSuccess {
case a:String => {
ret = 1
println(ret) //prints "1"
}
case a:Int => {
ret = 2
println(ret) //prints "2"
}
}
ret //returns None
}
ret
返回为无,不会更改为1
或2
。那么这是否意味着无法返回onSuccess块中变量ret
的值?然而,这似乎有效:
var a : Any = None
{
a = 1
println("inside "+ a ) //prints "inside 1"
}
println(a) // prints "1"
我将来可以在onSuccess块中做些什么,以便将ret
的值作为1
或2
返回,具体取决于未来的结果是整数还是串?对于scala,这种情况下的范围规则是什么? (我正在使用akka)。任何帮助表示赞赏。感谢。
答案 0 :(得分:2)
这里的问题不是范围界定,而是时间问题。
ret
初始化为None
。arg
邮件发送给someActor
,后者将返回未来。ret
。ret
的值,该值仍为None
。ret
的值,然后打印它。但当然,这不能及时返回并改变之前已经返回的值。所以,为了回答你的问题,你可以在onSuccess中做任何事情,它会及时返回并改变已经返回的值。但有两种选择。一种替代方法是阻止直到将来完成,然后确定是返回1还是2.另一种方法是返回Future[Int]
,以便调用者可以决定是否要阻止结果。这个代码实际上比你的代码简单:
def futureFunction(arg:Any):Future[Int] = {
implicit val timeout = Timeout(10 seconds)
val f: Future[Any] = someActor ? arg
f.map {
case a:String => 1
case a:Int => 2
}
}
如果您确实需要阻止,可以在futureFunction内部或外部使用Await.result
,具体取决于您要阻止的位置。
答案 1 :(得分:1)
在futureFunction
中,在ret
处理程序运行之前返回onSuccess
。当发生这种情况时,ret
将变为1
或2
,但此时已为时已晚。
您要使用的是Future.map
someActor ? arg map {
case a:String => 1
case a:Int => 2
}
请注意,futureFunction
必须返回Future
,否则您必须在函数内调用Await.result
才能阻止,直到结果可用。