多ajax请求的各类解决方案(同步, 队列, cancel请求) •多个ajax请求同时发送,相互无依赖。 •多个ajax请求相互依赖,必须有先后顺序。 •多个请求被同时发送,只需要最后一个请求。 第1种case 应用场景: 这个场景很多,一个页面打开是多个区域同时请求后台得到各自的数据,没依赖,没顺序。 处理方案: 直接用jquery的ajax函数。这个用的非常多,这里从略,可看后面的代码中例子。 第2种case 应用场景: 多个ajax请求,需要顺序执行,后一个ajax请求的执行参数是前一个ajax的结果。例如: 用户登录后我们发送一次请求得到用户的应用ID,然后利用应用ID发送一次请求得到具体的应用内容(例子虽然不是太恰当,但基本就是这个意思了)。 处理方法: 1. 利用ajax参数async设置为false,进行同步操作。(这个方法只适合同域操作,跨域需使用下面两种方法) 2. 利用ajax嵌套(这个同第1种情况) 3. 利用队列进行操作 jquery ajax队列操作核心代码: 复制代码 代码如下: (function ($) { var ajaxRequest = {}; $.ajaxQueue = function (settings) { var options = $.extend({ className: 'DEFEARTNAME' }, $.ajaxSettings, settings); var _complete = options.complete; $.extend(options, { complete: function () { if (_complete) _complete.apply(this, arguments); if ($(document).queue(options.className).length > 0) { $(document).dequeue(options.className); } else { ajaxRequest[options.className] = false; } } }); $(document).queue(options.className, function () { $.ajax(options); }); if ($(document).queue(options.className).length == 1 && !ajaxRequest[options.className]) { ajaxRequest[options.className] = true; $(document).dequeue(options.className); } }; })(jQuery); 第3中case 应用场景: 比较典型的是autocomplete控件的操作,这个我们可以使用第2种情况的处理方法,但我们可能只需要最后次按键后返回的结果,这样利用第2种处理方法未免有些浪费。 处理方法: 保留最后一次请求,cancel之前的请求。 复制代码 代码如下: (function ($) { var jqXhr = {}; $.ajaxSingle = function (settings) { var options = $.extend({ className: 'DEFEARTNAME' }, $.ajaxSettings, settings); if (jqXhr[options.className]) { jqXhr[options.className].abort(); } jqXhr[options.className] = $.ajax(options); }; })(jQuery); 对于这些case都是在多个ajax请求,响应时间不能控制的情况。下面是完整Demo代码。 复制代码 代码如下: (function ($) { var jqXhr = {}, ajaxRequest = {}; $.ajaxQueue = function (settings) { var options = $.extend({ className: 'DEFEARTNAME' }, $.ajaxSettings, settings); var _complete = options.complete; $.extend(options, { complete: function () { if (_complete) _complete.apply(this, arguments); if ($(document).queue(options.className).length > 0) { $(document).dequeue(options.className); } else { ajaxRequest[options.className] = false; } } }); $(document).queue(options.className, function () { $.ajax(options); }); if ($(document).queue(options.className).length == 1 && !ajaxRequest[options.className]) { ajaxRequest[options.className] = true; $(document).dequeue(options.className); } }; $.ajaxSingle = function (settings) { var options = $.extend({ className: 'DEFEARTNAME' }, $.ajaxSettings, settings); if (jqXhr[options.className]) { jqXhr[options.className].abort(); } jqXhr[options.className] = $.ajax(options); }; })(jQuery); var ajaxSleep = (function () { var _settings = { type: 'GET', cache: false, success: function (msg) { var thtml = $('#txtContainer').html(); $('#txtContainer').html(thtml + "
" + msg); } }; return { get: function (seconds, mode, isAsync) { var mode = mode || 'ajax', isAsync = isAsync || false; $[mode]($.extend(_settings, { url: "ResponsePage.aspx?second=" + seconds, async: isAsync, className: 'GET' })); }, post: function (seconds, mode, isAsync) { var mode = mode || 'ajax', isAsync = isAsync || false; $[mode]($.extend(_settings, { type: 'POST', url: "PostPage.aspx", data: { second: seconds }, async: isAsync, className: 'POST' })); } }; } ()); var launch = function (settings) { $('#txtContainer').html(''); var mode = settings.mode, isAsync = settings.isAsync; ajaxSleep.get(12, mode, isAsync); ajaxSleep.get(10, mode, isAsync); ajaxSleep.get(8, mode, isAsync); ajaxSleep.post(6, mode, isAsync); ajaxSleep.post(4, mode, isAsync); ajaxSleep.post(2, mode, isAsync); } $(document).ready(function () { //第1种case $('#btnLaunchAsync').click(function () { launch({ isAsync: true }); }); //第2种case $('#btnLaunchSync').click(function () { launch({}); }); //第2种case $('#btnLaunchQueue').click(function () { launch({ mode: 'ajaxQueue', isAsync: true }); }); //第3种case $('#btnLaunchSingle').click(function () { launch({ mode: 'ajaxSingle', isAsync: true }); }); }); default.html 复制代码 代码如下:
PostPage.aspx & ResponsePage.aspx 复制代码 代码如下: //ResponsePage.aspx protected void Page_Load(object sender, EventArgs e) { int seconds = int.Parse(Request.QueryString["second"]); Thread.Sleep(seconds*1000); Response.Write("GET: selpt for "+ seconds.ToString() +" sec(s)"); } //PostPage.aspx protected void Page_Load(object sender, EventArgs e) { int seconds = int.Parse(Request.Form["second"]); Thread.Sleep(seconds * 1000); Response.Write("POST: selpt for " + seconds.ToString() + " sec(s)"); } 后注: 个人能力有限,如有错误敬请指点。这些只是些根据一些特定情况下的处理,如果一个ajax请求能解决的问题切勿利用两个请求来处理,毕竟需要占用资源。我还是相信没有最好的方案,只有最适合的方案。