Appcan开发笔记:结合JQuery的$.Deferred()完善批量异步发送
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
结合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都没有还是自己扩展的),所以这个方法也抛弃了。