多ajax请求的各类解决方案(同步, 队列, cancel请求)
程序员文章站
2022-04-14 11:41:35
•多个ajax请求同时发送,相互无依赖。 •多个ajax请求相互依赖,必须有先后顺序。 •多个请求被同时发送,只需要最后一个请求。 第1...
•多个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 + "<br />" + 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
<!doctype html public "-//w3c//dtd xhtml 1.0 transitional//en" "http://www.w3.org/tr/xhtml1/dtd/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="head1" runat="server">
<title></title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js" type="text/javascript"></script>
<script type="text/javascript" src="js/default.js"></script>
</head>
<body>
<form id="form1" runat="server">
<input type="button" id="btnlaunchasync" value="launch asynchronous request" />
<input type="button" id="btnlaunchsync" value="launch synchronous request" />
<input type="button" id="btnlaunchqueue" value="launch requested queue" />
<input type="button" id="btnlaunchsingle" value="launch single request" />
<div id="txtcontainer"></div>
</form>
</body>
</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请求能解决的问题切勿利用两个请求来处理,毕竟需要占用资源。我还是相信没有最好的方案,只有最适合的方案。
•多个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 + "<br />" + 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
复制代码 代码如下:
<!doctype html public "-//w3c//dtd xhtml 1.0 transitional//en" "http://www.w3.org/tr/xhtml1/dtd/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="head1" runat="server">
<title></title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js" type="text/javascript"></script>
<script type="text/javascript" src="js/default.js"></script>
</head>
<body>
<form id="form1" runat="server">
<input type="button" id="btnlaunchasync" value="launch asynchronous request" />
<input type="button" id="btnlaunchsync" value="launch synchronous request" />
<input type="button" id="btnlaunchqueue" value="launch requested queue" />
<input type="button" id="btnlaunchsingle" value="launch single request" />
<div id="txtcontainer"></div>
</form>
</body>
</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请求能解决的问题切勿利用两个请求来处理,毕竟需要占用资源。我还是相信没有最好的方案,只有最适合的方案。