0

首先,这在 Grails 2.5.4 中不是问题。

我正在对我的 Grails 控制器进行角度 AJAX 调用,但 Grails 控制器从不响应。前端调用看起来像这样..

     $http({
            method: "GET",
            url: actionLink,
            params: {}
        }).then(function successCallback(response) {

            console.log("Yaaay, I got back with some sort of response");
        }, function errorCallback(response) {
            console.log("ERROR PULLING DETAIL")
        });

我已经确认 AJAX 调用不调用任何类型的 .async.task 的其他控制器立即返回,并且很好。然而,这个端点有两个 async.task,我可以知道在定义第一个 async.task 之后触发了 asyncStarted 标志:

        log.info("ASYNC CHECK-1 - asyncSupported=" + request.asyncSupported + ", asyncStarted=" + request.isAsyncStarted())

        def availabilityTask = Item.async.task {

            JSON availability = itemService.getItemAvailabilityAsJSON(itemInstance)

            availability
        }

        log.info("ASYNC CHECK-2 - asyncSupported=" + request.asyncSupported + ", asyncStarted=" + request.isAsyncStarted())

第一个 request.isAsyncStarted() 返回 false,第二个返回 true。当我将日志记录一路调高并在我的日志中注意到这条消息时,我被告知这是一个异步问题:

2017-02-08 18:47:54 调试 ogweb.servlet.mvc.GrailsDispatcherServlet:为并发处理打开响应

以前在 Grails 2.5.4 中,我只需要简单地调用 availabilityTask.get() 并使用指定的适当模型和布局来渲染视图。现在看来,我必须这样做才能使响应刷新到前端:

   if (request.isAsyncStarted()) {
            final AsyncContext ac = request.asyncContext;
            log.info("Calling to complete async request")
            ac.dispatch()
   }

这看起来很烦人,因为我没有将任何承诺或可调用对象传递到模型中,而且我已经在检查任务是否完成。我是否遗漏了一些迫使我这样做的东西,或者是这种预期且记录不充分的行为(Grails 文档中关于 Async 的任何地方都没有提到需要调用 .dispatch() 来刷新异步请求..

2017 年 2 月 10 日更新

我试图将承诺传递给模型,例如:

        def availabilityTask = Item.async.task {
            JSON availability = itemService.getItemAvailabilityAsJSON(itemInstance)

            availability
        }
        render view : "myView", model:[nonAsyncItems, availabilityTask]

认为结果转换器会在模型中检测到 Promise 但没有发生自动调度。我想模仿我在 Grails Async 文档中看到的内容,但我想整个模型必须是 PromiseMap 才能发生自动调度?(当我有一个控制器拉同步和异步数据时,这并不理想)

文档部分:

    import static grails.async.Promises.*

    def index() {
       render view:"myView", model: tasks( one:{ 2 * 2 },
                                           two:{ 3 * 3 } )
    }

无论如何,目前看来我的选择是将带有任何 *.async.task 的控制器包装在更大的任务 {} 闭包中,或者手动管理调度。

4

1 回答 1

1

确实,Grails 以前没有启动和异步请求任务。这种行为是错误的,因为如果任务需要时间,那么原始请求可能会在任务有时间完成之前完成并返回到线程池,从而导致不可预测的行为和异常。

此行为在 Grails 3 中已得到纠正。如果您从控制器返回Promisetask方法创建的,那么 Grails 将自动dispatch()为您处理调用。你可以在这里看到这个https://github.com/grails/grails-core/blob/3.2.x/grails-plugin-async/src/main/groovy/org/grails/plugins/web/async/mvc/AsyncActionResultTransformer .groovy#L72

于 2017-02-10T07:23:11.060 回答