播放2.0 Scala和异步回调

播放2.0 Scala和异步回调,scala,playframework-2.0,Scala,Playframework 2.0,我想对我的数据库进行两次调用,这将需要一段时间才能返回结果,我不想阻止当前线程。我使用Akka Futures来包装数据库调用 我不想等待(阻塞)两个调用都返回,而是想指定一个要调用的回调函数,然后它可以呈现响应。我该怎么做?这是我的控制器代码: def showPie = IsAuthenticated(Roles.validator) { user => implicit request => val eventUid = request.session.get(Even

我想对我的数据库进行两次调用,这将需要一段时间才能返回结果,我不想阻止当前线程。我使用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))
}

你很接近。您可以简单地调用
map
,承诺处理它。在异步块内,它保持非阻塞状态。(参见“异步结果”)

编辑: 从下面的评论中,让我们仔细看看异步块。code>Async接受一个
承诺
,并返回一个
AsyncResult
,它是
结果
的子类型(这是
操作
需要的)


由于
map
函数在
promise
完成时被调用,因此保持非阻塞状态。整个程序块以
AsyncResult
快速返回,然后播放!以类似的方式管理它,在它完成时返回给客户(并释放Play!在此期间做其他事情)。

您知道它是如何工作的吗?《承诺》是否经常被调查,看它是否准备好了,如果没有,阿克卡会去做其他的工作?比这更好。因为您的调用是在将来执行的,所以它们会在幕后添加到参与者的消息队列中,当消息队列可用时(通常非常快),它会处理它,然后调用任何完成函数。在Akka actors上,map、onComplete、onSuccess和onFailure都是这样工作的。您最后的承诺(序列)只是包装其他部分,并在每个部分完成后执行侦听功能。由于所有这些都发生在回调中,因此不需要轮询。
map
调用返回另一个Promise,
Async
乐意接受它作为函数文本返回值。然后,它向该承诺添加一个侦听器方法,将消息返回给客户端。整个过程最终是非阻塞的,不需要轮询。
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)
        }
    }
}
    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
    }