我对Scala Future
的工作原理感到困惑。有人可以解释代码有什么问题:
import scala.concurrent._
import scala.concurrent.ExecutionContext.Implicits.global
val numbers = List(1,2,3,4,5,6,7,8,9,10)
def showNumbers() = {
numbers
}
val futueNumber = future {
showNumbers.filter((a: Int) => a % 2 == 0)
}
futueNumber onSuccess {
case resultList => resultList
}
futueNumber
我希望收到一个结果:
List(1,2,3,4,5,6,7,8,9,10)
但REPL输出:
res1: scala.concurrent.Future[List[Int]] = scala.concurrent.impl.Promise$DefaultPromise@3644febc
请给我一个简短的提示,如何解决这个问题
答案 0 :(得分:1)
简单的答案是,您需要等待未来让您的示例工作:
val result = Await.result(futureNumber, 1.second)
然而,未来的目的不是像Await
那样阻止异步工作,而是在可用时使用未来的结果。
使用future
的关键是理解它实际上并不包含计算的价值,而是承诺在未来的某个时刻,它将提供该值。
通常的用例是进入需要一些工作的服务器的请求,这可能需要一些时间并且自己等待IO,如下所示:
def receiveMsg(msg: String, caller: Caller) = {
doSomeAsyncWork(msg).map(response => caller.send(response)
}
即。您使用send
方法调用的对象在doSomeAsyncWork
完成时要调用,但是您不希望阻止当前线程,直到future
完成。相反,您map
future
,这意味着response => caller.send(response)
完成后会为您调用doSomeAsyncWork
。
答案 1 :(得分:0)
futureNumber的类型为Future[List[Int]]
,因为您在
val futureNumber = future {
showNumbers.filter((a: Int) => a % 2 == 0)
}
因此,当您打印futureNumber时,就是打印出来的内容。该变量不会被重新分配给未来的值!如果要打印未来的值,则需要在onSucess回调中执行:
futureNumber onSuccess {
case resultList => println(resultList)
}
或者,您可以使用
阻止等待未来import scala.concurrent.ExecutionContext.Implicits.global
import duration._
val theList = scala.concurrent.Await.result(futureNumber, 10 seconds)
println(theList)
虽然如果在REPL中完成,这可能不起作用。
Future
类型的重点在于它充当标记,提醒您并发性并且应该帮助您更好地处理它。