Joh*_*ith 3 scala playframework-2.0
我想对我的数据库进行两次调用,这将需要一段时间才能返回结果,我不想阻止当前线程.我用Akka Futures来包装数据库调用.
我没有等待(阻塞)两个调用返回,而是指定要调用的回调函数,然后可以呈现响应.我怎么做?这是我的控制器代码:
def showPie = IsAuthenticated(Roles.validator) { user => implicit request =>
val eventUid = request.session.get(EventUid).get
val printed = Akka.future(TicketRepository.getCountForState(eventUid, "Printed"))
val validated = Akka.future(TicketRepository.getCountForState(eventUid, "Validated"))
//this would be evil, because it would block: Ok(views.html.pie(printed.await(1000).get, validated.await(1000).get))
//create a promise for all the promised results
val promise = Promise.sequence(List(printed, validated))
//this doesnt work, but how can I make it work WITHOUT blocking this thread?
promise.callWhenResultIsReady(Ok(view.html.pie(promise.get))
}
Run Code Online (Sandbox Code Playgroud)
你很亲密 您可以简单地致电map承诺来处理它.在异步块内部,它保持非阻塞状态.相关文档(参见"AsyncResult").
def showPie = IsAuthenticated(Roles.validator) { user => implicit request =>
val eventUid = request.session.get(EventUid).get
val printed = Akka.future(TicketRepository.getCountForState(eventUid, "Printed"))
val validated = Akka.future(TicketRepository.getCountForState(eventUid, "Validated"))
//create a promise for all the promised results
val promise = Promise.sequence(List(printed, validated))
Async {
promise map { res =>
Ok("Got it!" + res)
}
}
}
Run Code Online (Sandbox Code Playgroud)
编辑:
从下面的评论中,让我们仔细看看异步块.Async取aPromise,并返回aAsyncResult,这是Result(Action需要的)子类型.
Async {
// We take the promise, and add something akin to a callback
// function with `map`. This new function is called when `promise`
// is complete.
val result = promise map { res => // this is the redeemed promise
Ok("Got it!" + res)
}
result // this is the new promise
}
Run Code Online (Sandbox Code Playgroud)
由于map函数在promise完成时被调用,因此保持非阻塞状态.整个块快速返回AsyncResult,并播放!通过在完成时返回客户端(并释放Play!同时执行其他操作)以类似的方式管理它.