我想在Grails中利用多線程來處理AJAX調用。該網頁觸發AJAX調用,控制器分配一個新線程完成該任務,並在完成時返回並呈現結果。這是我的嘗試。它失敗了。貌似第二個AJAX調用並沒有被解僱。Grails使用Promises來回答AJAX調用
在gsp中的javascript:兩個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();}
我的理解用戶對象是一個承諾創建和處理我的工作,這是完成時,該數據應正常類返回到迴應AJAX呼叫的網頁。所以.done()
函數也應該被觸發,導致流向另一個AJAX調用。但是,從不觸發done()
。我在瀏覽器控制檯中看不到「履帶完成」。
在我的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
請有人可以告訴我我在做什麼錯在這裏。非常感謝您的幫助!
這不是它的工作原理。請求已在此刻處理完畢。你必須在那裏做出響應(或使用Servlet 3.0異步,但無論如何,我不知道它如何幫助你)。只是從服務器動作中刪除異步代碼,你不需要它,它也沒有任何意義 –
,像'FrameworkController.crawlStarted = true'使你的控制器非線程安全,你不應該存儲用戶狀態共享變量(控制器類只有一個實例,在多個請求之間共享) –
@IgorArtamonov只有當設置了'static scope ='singleton''時,纔會這樣。每默認每個請求都會創建一個新的控制器實例所以它可以放在 – injecteer