斯卡拉:行动的未来

时间:2014-06-26 21:05:05

标签: scala future

我对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

请给我一个简短的提示,如何解决这个问题

2 个答案:

答案 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类型的重点在于它充当标记,提醒您并发性并且应该帮助您更好地处理它。