我试图利用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
请有人告诉我这里我做错了什么。真的很感谢你的帮助!
答案 0 :(得分:0)
每个servlet请求已经在一个线程中提供,因此不需要产生另一个线程。您可以在操作中生成新线程 - 使用new Thread().start()
或使用GPars - 并不重要。
重要的是,您必须等待(使用thread.join()
或类似)直到线程完成,以便您的操作可以提供JS代码所期望的结果