在开发中一定有这种情况:
一个简易的需求,点一个按钮,则向服务器请求资源,不作处理时,多次点击后会有很多个请求在等待。
最粗暴的解决方式是点一次就将按钮disable掉,比如
$("input[type=submit]").attr('disabled',false)但这种形式缺点也很多,还有稍微优雅一点的方式完全由JS来控制,就是使用一个变量来保存状态:
var post_flag = false;
function post(){
//如果正在提交则直接返回,停止执行
if(post_flag) return;
//标记当前状态为正在提交状态
post_flag = true;
$.ajax({//进入AJAX提交过程
url:'/post.php',
data:{a:1,b,1}
})
.done(function () {
// something
})
.always(function () {
post_flag = false;
})
}
但无论如何每个请求都需要写这样一段重复性的代码,又臭又长,还和业务逻辑混在一起,也不是最佳的解决方案。
那怎么才能把这个近似的业务逻辑封装起来呢?这里就用到了jquery ajax的预处理功能(一般其他的ajax工具也都有预处理函数)
这里只针对jquery:
!function () {
/*设置ajax全局默认值*/
$.ajaxSetup({
async: true,
cache: false,
dataType: 'json'
});
/*ajax预处理缓存*/
var ajaxRequestList = {};
/*
判断唯一标识,同一个ajax只能同时存在一次
single(string): 唯一标识
mine(boolean): 如果ajax标识重复则用自身(true)还是原来的
once(boolean): 是否唯一,唯一(true)则只会请求成功一次
*/
$.ajaxPrefilter(function(options, originalOptions, jqXHR) {
if (typeof originalOptions.single === 'string') {
if (!ajaxRequestList[originalOptions.single]) {
ajaxRequestList[originalOptions.single] = jqXHR;
if (originalOptions.once === true) {
jqXHR.fail(function() {
delete ajaxRequestList[originalOptions.single];
});
} else {
jqXHR.always(function() {
delete ajaxRequestList[originalOptions.single];
});
}
} else {
if (originalOptions.mine === true) {
ajaxRequestList[originalOptions.single].abort();
} else {
jqXHR.abort();
}
}
}
});
}();基本思路就是利用预处理器ajaxPrefilter将请求信息储存在一个对象中,可以通过传入的额外标志来控制重复提交
$.ajax({
url: 'post.php',
type: 'POST',
data: {id: 0},
single: 'post_1' // 唯一标识 当有这个标识存在,预处理器会拦截本次请求
})
.done(function (data) {
// something
});
$.ajax({
url: 'post.php',
type: 'POST',
data: {id: 0},
single: 'post_2',
mine: true // 当single重复时用自身并放弃之前的ajax请求
})
.done(function (data) {
// something
});$.ajax({
url: 'post.php',
type: 'POST',
data: {id: 0},
single: 'post_3',
once: true // 只允许请求成功一次,一旦成功,这个single永远不会在发起请求
})
.done(function (data) {
// something
});通过预拦截器和这三个标识,可以很方便的应对基本所有情况,在项目中也没用发现任何问题
6272

被折叠的 条评论
为什么被折叠?



