Grails使用Promises来回答AJAX调用

时间:2015-12-10 13:15:50

标签: ajax multithreading grails

我试图利用Grails中的多线程来处理AJAX调用。该网页触发一个AJAX调用,控制器分配一个执行该作业的新线程,当它完成时,返回并呈现结果。这是我的尝试。它失败了。看似第二次AJAX调用根本没有被解雇。

在gsp中的gsp:两个AJAX调用。第一个在完成时触发第二个。

function asynchroCrawl(){
    var jsonData = $.ajax(
            {
                url : "${createLink(controller:'environment', action:'asynchroCrawl')}",
                dataType : "json",
                async : true
            }).done(function(jsonData) {
                console.log("Crawler completed");
                crawlFinished=true;
                asynchroWordCloud();
    });
}
function asynchroWordCloud() {
    var jsonData = $.ajax(
                    {
                        url : "${createLink(controller:'environment', action:'asynchroKeywords')}",
                        dataType : "json",
                        async : false
                    }).done(function(jsonData) {                    
                keywordFinished = true; 
            });
}

在控制器中:省略了另一个acton函数。

def asynchroCrawl={
    User u=session.getAttribute("user");
    FrameworkController.crawlStarted=true;
    println "Crawling task started.";
    def p=task{
        NetworkGenerator.formNetwork(u);
    }
    p.onError { Throwable err -> println "An error occured \n${err.message}" }
    p.onComplete { result ->
        println "User crawl complete.";
        FrameworkController.crawlComplete=true;
        render u as JSON;
        return;
    }
}

NetworkGenerator只是一个普通的类,可以运行某些作业并使用User.withTransaction{u.merge();}更新User对象

我的理解是创建了一个Promise并处理我的工作,当它完成时,数据应该返回到回答AJAX调用的网页。因此,也应该触发.done()函数,将流引导到另一个AJAX调用。但是,永远不会触发done()。我看不到" Crawler完成"在我的浏览器控制台中打印。

在我的IDE控制台中,我看到"用户抓取完成。",表示承诺已完成。但接下来有一个例外,说:

2015-12-10 21:05:47,540 [Actor Thread 7] ERROR gpars.LoggingPoolFactory  -  Async execution error: null
Message: null
Line | Method
->> 1547 | notifyAttributeAssigned in org.apache.catalina.connector.Request
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
|   1538 | setAttribute            in     ''
|    541 | setAttribute . . . . .  in    org.apache.catalina.connector.RequestFacade
|    288 | setAttribute            in org.apache.catalina.core.ApplicationHttpRequest
|    431 | storeGrailsWebRequest . in org.codehaus.groovy.grails.web.util.WebUtils
|     61 | doCall                  in org.codehaus.groovy.grails.plugins.web.async.WebRequestPromsiseDecorator$_decorate_closure1
|     -1 | call . . . . . . . . .  in     ''
|     61 | doCall                  in org.grails.async.factory.gpars.GparsPromise$_onComplete_closure1
|     -1 | call . . . . . . . . .  in     ''
|     62 | run                     in groovyx.gpars.dataflow.DataCallback$1

请有人告诉我这里我做错了什么。真的很感谢你的帮助!

1 个答案:

答案 0 :(得分:0)

每个servlet请求已经在一个线程中提供,因此不需要产生另一个线程。您可以在操作中生成新线程 - 使用new Thread().start()或使用GPars - 并不重要。

重要的是,您必须等待(使用thread.join()或类似)直到线程完成,以便您的操作可以提供JS代码所期望的结果