appcan的 uexXmlHttpMgr.send 或者 appcan.ajax無法同步請求(沒有找到這個屬性),只能非同步,造成迴圈多次提交時由於延遲或網路堵塞等原因無法同步響應,導致提交順序混亂,執行完後回調錯誤或丟數據,如傳統方法(這裡已經引用的JQ包) 1 var data=[]; 2 va ...
appcan的 uexXmlHttpMgr.send 或者 appcan.ajax無法同步請求(沒有找到這個屬性),只能非同步,造成迴圈多次提交時由於延遲或網路堵塞等原因無法同步響應,導致提交順序混亂,執行完後回調錯誤或丟數據,如傳統方法(這裡已經引用的JQ包)
1 var data=[]; 2 var d=[1,2,3,4,5,6]; 3 $.each(d, function(i, v) { 4 var req = uexXmlHttpMgr.create({ 5 method : "GET", 6 url :myurl 7 }) 8 uexXmlHttpMgr.send(req, 0, function(status, resStr, resCode, resInfo) { 9 if (status == 1) { 10 data.push(i+"OK"); 11 } 12 }); 13 }); 14 alert(JSON.stringify(data))
輸出結果為[],因為調用了多次回發,輸出data時each和請求都沒有執行完畢所以data中肯定是沒有值的。 這時引用$.Deferred(),例子如下
1 var dtd = $.Deferred(); // 新建一個Deferred對象 2 var wait = function(dtd){ 3 var tasks = function(){ 4 alert("執行完畢!"); 5 dtd.resolve(); // 改變Deferred對象的執行狀態 6 }; 7 setTimeout(tasks,5000); 8 return dtd; 9 }; 10 $.when(wait(dtd)) 11 .done(function(){ alert("哈哈,成功了!"); }) 12 .fail(function(){ alert("出錯啦!"); });
這裡不做過多說明,$.Deferred()的用法詳解:
http://www.ruanyifeng.com/blog/2011/08/a_detailed_explanation_of_jquery_deferred_object.html
http://api.jquery.com/category/deferred-object/ 結合appcan請求 得到如下代碼1 var d = [1, 2, 3, 4, 5, 6]; 2 var data = []; 3 var sendalldata = function() { 4 var dtdall = $.Deferred(); 5 $.each(d, function(i, v) { 6 var io = i; 7 var req = uexXmlHttpMgr.create({ 8 method : "GET", 9 url : myurl 10 }) 11 uexXmlHttpMgr.send(req, 0, function(status, resStr, resCode, resInfo) { 12 if (status == 1) { 13 console.log("結果" + i + ":" + resStr); 14 resStr = eval('(' + resStr + ')'); 15 data.push(resStr.toString()) 16 if (d.length == count) { 17 dtdall.resolve(JSON.stringify(data)); 18 } 19 } 20 }); 21 }) 22 return dtdall.promise(); 23 } 24 $.when(sendalldata()).done(function(v1) { 25 console.log(v1) 26 v1 = eval('(' + v1 + ')'); 27 console.log("結果v1" + ":" + JSON.stringify(v1)); 28 });
輸出結果為預期(運行環境為ID4.0)。 另外還有兩種解決辦法,第一種是網上比較常見的無限迴圈,但是如果還有複雜的回調代碼就會很混亂,以上代碼中 if (d.length == count) {... 其實也有點無限迴圈的意思; 第二種是使用js原生方法promise,但是appcan內核還沒有到ES6(Array.prototype.filter和Array.prototype.map都沒有還是自己擴展的),所以這個方法也拋棄了。