我有一个提供Context的函数:
def buildContext(s:String)(request:RequestHeader):Future[Granite.Context] = {
.... // returns a Future[Granite.Context]
}
Run Code Online (Sandbox Code Playgroud)
然后我有另一个函数,它使用Context来返回一个Option [Library.Document]:
def getDocument(tag: String):Option[Library.Document] = {
val fakeRequest = play.api.test.FakeRequest().withHeaders(CONTENT_TYPE -> "application/json")
val context = buildContext(tag)(fakeRequest)
val maybeDoc = context.getDocument //getDocument is defined on Granite.Context to return an Option[Library.Document]
}
Run Code Online (Sandbox Code Playgroud)
如果Future已经返回,这段代码将如何考虑?我已经看到/ yield曾经等待返回,但我总是认为for/yield只是将事情拼凑在一起并且与等待Futures返回没有任何关系.我有点卡在这里,并不是真的没有正确的问题要问!
fla*_*ian 10
另外两个答案是误导性的.for yieldScala中的A 是一个转换为map或flatMap链的编译器原语.Await如果可以避免使用,请不要使用,这不是一个简单的问题.
您正在介绍阻止行为,并且您尚未意识到阻止时所做的系统性损害.
当涉及到Future,map并flatMap做不同的事情:
将 在未来完成时执行map.这是一种进行类型安全映射的异步方法.
val f: Future[A] = someFutureProducer
def convertAToB(a: A): B = {..}
f map { a => convertAToB(a) }
Run Code Online (Sandbox Code Playgroud)
flatMap
是你用来链接东西的东西:
someFuture flatMap {
_ => {
someOtherFuture
}
}
Run Code Online (Sandbox Code Playgroud)
相当于上述内容:
for {
result1 <- someFuture
result2 <- someOtherFuture
} yield result2
Run Code Online (Sandbox Code Playgroud)
在Play中你会Async用来处理上面的事情:
Async {
someFuture.map(i => Ok("Got result: " + i))
}
Run Code Online (Sandbox Code Playgroud)
更新
我误解了你对Play的使用.不过,它并没有改变任何东西.您仍然可以使您的逻辑异步.
someFuture onComplete {
case Success(result) => // doSomething
case Failure(err) => // log the error etc
}
Run Code Online (Sandbox Code Playgroud)
在异步思考时的主要区别在于,您始终必须map并且flatMap在Futures中执行其他所有操作才能完成任务.性能提升很大.
你的应用越大,收益越大.
当Future你在a上使用for-comprehension时,你不是在等待它完成,你只是说:当它完成时,像这样使用它,For-comprehension Future在这种情况下返回另一个.
如果您想等待将来完成,您应该使用Await如下:
val resultContext = Await.result(context , timeout.duration)
Run Code Online (Sandbox Code Playgroud)
然后对它运行getDocument方法:
val maybeDoc = resultContext.getDocument
Run Code Online (Sandbox Code Playgroud)
编辑
然而,与期货合作的常用方法是等到你之前的最后一刻Await.正如另一个答案所指出的,Play Framework通过允许您返回来做同样的事情Future[Result].所以,一个好的方法就是只使用for-comprehensions并让你的方法返回Futures等,直到你想要最终返回结果的最后一刻.
| 归档时间: |
|
| 查看次数: |
7097 次 |
| 最近记录: |