在Playframework中,如何在控制器中使用表单绑定执行异步作业?

时间:2016-09-12 00:54:17

标签: playframework

在我的控制器中,我有一个简单的表单绑定和Slick数据库(删除)操作:

def deleteApp = Action { implicit request =>
    deletedAppForm.bindFromRequest.fold(
        formWithErrors => {
            Redirect(routes.AppController.index())
        },
        form => {
            for (id <- form.idx) {
                appDao.delete(id) // database deleting with Slick
            }

            Redirect(routes.AppController.index())
        }
    )
}

你可以看到我在for循环中进行了Slick删除,这是因为我有一个要删除的条目列表。 这部分是阻止的,我希望它是非阻塞的。

我试图用:

替换整个for循环
val f: List[Future[Int]] = form.idx.map{appDao.delete(_)}
f.map(_ => Redirect(routes.AppController.index()))

而且(当然)编译器不喜欢它。

我的问题是:一般情况下,如何在控制器中使用表单绑定进行异步作业?

由于

3 个答案:

答案 0 :(得分:2)

我认为,更好的解决方案是将appDao.delete改进为非阻塞。在您可以使用之后:

def deleteApp = Action.async { implicit request =>
        deletedAppForm.bindFromRequest.fold(
            formWithErrors => {
                Future.successful(Redirect(routes.AppController.index()))
            },
            form => {
              Future.sequence(form.idx.map(appDao.delete(_)))
                    .map(_ => Redirect(routes.AppController.index()))                    
            }
        )
    }
}

答案 1 :(得分:1)

Steve,通常是事务的异步部分是通过Actions完成的。您可能希望尝试Action.async操作以实现非阻塞。我过去曾尝试使用JavaActions和Async来尝试类似的东西。在scala上,您可能想要引用此question并查看是否有帮助

答案 2 :(得分:0)

“也许”这是正确的,虽然该功能有效,但我不确定它是否真正无阻塞。

def deleteApp = Action.async { implicit request =>
    Future {
        deletedAppForm.bindFromRequest.fold(
            formWithErrors => {
                Redirect(routes.AppController.index())
            },
            form => {
                for (id <- form.idx) {
                    appDao.delete(id)
                }

                Redirect(routes.AppController.index())
            }
        )
    }
}

现在Action变为Action.async,整个代码块位于Future内,implicit request除外。