鉴于我们必须避免......
1)修改状态2)阻塞
...对于Future来说,什么是正确的端到端使用?
使用Futures的一般做法似乎是通过使用map,flatMap等将它们转换为其他Futures,但永远创造Futures并不好 .
是否总会在某处调用onComplete,方法是将Future的结果写入应用程序外部的某个位置(例如Web套接字;控制台;消息代理)或者是否存在访问结果的非阻塞方式?
关于Scaladocs中期货的所有信息 - http://docs.scala-lang.org/overviews/core/futures.html似乎最终写入控制台 . onComplete不会返回任何内容,所以我们不得不最终做一些"fire-and-forget" IO .
例如致电 println
f onComplete {
case Success(number) => println(number)
case Failure(err) => println("An error has occured: " + err.getMessage)
}
但是在更复杂的情况下,我们想要用未来的结果做更多的事情呢?
例如,在Play框架中,Action.async可以返回Future [Result],框架处理其余部分 . 它最终是否会期望永远不会从未来获得结果?
我们知道用户需要返回一个 Result
,那么框架如何只使用Unit方法来实现呢?
是否有一种非阻塞的方法来检索未来的 Value 并在应用程序的其他地方使用它,或者是对Await的调用是不可避免的?
4 回答
最佳做法是使用诸如
onComplete
,onSuccess
,onFailure
之类的回调进行副作用操作,例如:记录,监控,I / O.如果您需要继续执行
Future
计算的结果而不是执行副作用操作,则应使用map
来访问计算结果并对其进行组合 .未来会返回一个单位,是的 . 那是因为它是一个异步触发器 . 您需要注册回调才能收集结果 .
从你引用的scaladoc(带我的评论):
或者不是打印,而是可以对结果做一些事情:
试试这个:
那么这里发生了什么?
您正在定义要在不同的
thread
上执行的计算 .所以你
Future { 43 }
立即返回 .然后你可以等待它并收集结果(通过
Await.result
)或在其上定义计算而无需等待它完成(通过map
等...)实际上,你所谈论的那种未来用于副作用 . Future返回的结果取决于它的类型:
例如,我可以将Future [Int]的结果发送给另一个Future:
如您所知,未来是一个同时发生的过程 . 所以你可以在将来得到它的结果(也就是说,使用诸如onComplete之类的方法)或者通过显式阻塞当前线程直到它获得一个值:
通常,当您开始处理异步流程时,您必须考虑可能永远不会发生的反应 . 使用链式期货就像宣布可能随时可能被破坏的一系列事件 . 因此,等待Future的 Value 绝对不是一个好习惯,因为你可能永远不会得到它:
尝试在事件方面考虑更多,而不是在程序方面 .