日期:2014-05-16 浏览次数:20409 次
使用ExtJs处理批量数据时,使用for循环通过Ext Ajax调用后台,代码如下:
for(var i=0; i<params.length; i++){ Ext.Ajax.request({ url:this.url, params:params[i], method:'POST', success:function(response) { }, scope:this }); }
因为Ajax是异步处理的,导致后台接收到的数据无法保持正常的次序,后台的逻辑就会出现错乱。
【思路】
最简单的思路就是将异步调用转换为同步调用,但找了很多办法,Ext.Ajax.request要支持同步发送需要修改核心代码,这个才目前的产品上是不允许的;其它的同步调用的方法暂时没有找到,于是放弃了此思路;
另外的思路就是Ext.Ajax.request真正处理结束后才执行下一次调用:
1. 此时Ext.Ajax.request的success回调是不行的,因为只在成功的时候才会执行此回调,因此需要使用callback回调方法;
2. 如果使用for循环,不会等到Ext.Ajax.request的回调,就进行下一个循环了,所以for循环不行;如果在Ext.Ajax.request没有回调前,在for中写一个等待的逻辑,例如while(isOk);显然也会有性能等诸多问题;
3. 如何才能解决2的问题,最好的办法是使用递归模拟for循环;
【执行】
添加一个递归函数:
batchProcess: function(index, length, params){ if(index >= length){ alert('处理结束'); return; }else{ Ext.Ajax.request({ url:this.url, params:params[index], method:'POST', success:function(response) { batchProcess(++index, length, params); }, scope:this }); } }
然后使用batchProcess(0, params.length, params);进行调用。
至此我们发现问题得到解决,此外还发现另外一个好处就是,我们可以控制批量执行时从第几条数据开始执行,例如从第3条开始执行:batchProcess(2, params.length, params);
【扩展:使用Java模拟异步处理,并使用递归同步调用】
【1:使用线程模拟Ext.Ajax.request调用】
package sync; /** * 使用线程模拟异步处理逻辑 * * @author 李文锴 * @since 2012-8-16 下午05:20:39 * */ public abstract class Asyn extends Thread { @Override public void run() { try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } onSuccess(); } /** * 当异步处理成功时的回调 * * @Description: * @author 李文锴 * @since:2012-8-16 下午05:21:32 */ public abstract void onSuccess(); }
【2:使用Java模拟for循环调用异步逻辑】
package sync; /** * for循环执行异步逻辑 * * @author 李文锴 * @since 2012-8-17 上午08:46:07 * */ public class AsynFor { public static void main(String[] args) { String[] params = { "aaa", "bbb", "ccc", "ddd" }; new AsynFor().asynProcess(params); } /** * 模拟对于异步方法执行for循环 * * @Description: * @param params * @author 李文锴 * @since:2012-8-17 上午08:32:22 */ public void asynProcess(String[] params) { for (int i = 0; i < params.length; i++) { doBusinessProcess(i, params[i]); } } /** * 异步调用执行业务逻辑 * * @Description: * @param index * @author 李文锴 * @since:2012-8-17 上午08:46:45 */ private void doBusinessProcess(final int index, final String data) { new Asyn() { @Override public void onSuccess() { System.out.println("业务执行:" + index); System.out.println(index + " : 业务完成后输出 => " + data + "\n"); } }.start(); } }
执行后输出如下:
业务执行:2 2 : 业务完成后输出 => ccc 业务执行:0 0 : 业务完成后输出 => aaa 业务执行:1 1 : 业务完成后输出 => bbb 业务执行:3 3 : 业务完成后输出 => ddd
我们发现并没有按照正常的次序执行,通过上面的Java代码复现了在ExtJs中会遇到的问题
【3:使用Java模拟递归处理批量异步逻辑同步执行问题】
package sync; /** * 使用递归模拟for循环处理业务逻辑,同步执行 * * @author 李文锴 * @since 2012-8-17 上午08:47:33 * */ public class SyncFor { public static void main(String[] args) { String[] params = { "aaa", "bbb", "ccc", "ddd" }; new SyncFor().syncProcess(0, params.length, params); } /** * 使用递归进行同步输出