现在有一个按钮 $btn,我们给它绑定了点击事件,让它点一次就发一次POST请求去后端提交统计数据:
var $btn = $('#btn');
$btn.click(function(){
$.ajax({ url: "a.php", type: 'POST', success: function(){
console.log(ret);
}});
});
但是如果用户在很短的时间内点了好几下按钮(比如在1s里快速地点了5下),会向服务器发送很多条数据,这样并发量大的情况下服务器可能吃不消。
而且有时候我们也希望当前一条请求结束了(服务器返回数据了)之后才可以发起第二条请求。
所以请你封装一个叫 $.smartAjax 方法来做防抖处理,它可以有一个参数smartType用于确定防抖方式——如果其值为 0 则要求在 500ms 内只允许发出一条请求;
如果参数smarType值为 1 则表示只允许在前一条收到服务器响应(包括失败的响应)后才可以继续发送新请求。
示例:
var $btn1 = $('#btn1');
var $btn2 = $('#btn2');
$btn1.click(function(){
//每500ms最多只会发出一条请求
$.smartAjax({ smartType: 0, url: "a.php", type: 'POST', success: function(){
console.log(ret);
}});
});
$btn2.click(function(){
//只有当前一条请求收到服务器响应了,才能再发出新的请求
$.smartAjax({ smartType: 1, url: "a.php", type: 'POST', success: function(){
console.log(ret);
}});
});
$.smartAjax = .... //实现它
实现
$.smartAjax = (function () {
var _time_start = 0,
_flag = 1; //用于判断是否可以发送请求
return function (opt) {
var noop = function () {},
validFun = function (f) {
return typeof f === 'function' ? f : null
},
smartType = opt && opt.smartType,
processResponse = function (callback) {
['success', 'error'].forEach(function (resFunName) {
var resFun = validFun(opt[resFunName]) || noop;
opt[resFunName] = function () {
callback();
resFun.call(this, arguments)
}
});
},
typeCallback = {
0: function () {
_flag && (_time_start = Date.now());
if(_flag==0 && Date.now() - _time_start > 300) {
_flag = 1;
_time_start = Date.now()
}
},
1: function () {
if(_time_start) { //防止先调用smartType=0再调用smartType=1会失效
_flag = 1;
_time_start = 0
}
processResponse(function(){
_flag = 1;
})
}
};
var hasSmartType = typeCallback[smartType];
hasSmartType && typeCallback[smartType]();
if(_flag) {
hasSmartType && (_flag = 0);
return $.ajax(opt);
} else {
return $.Deferred()
}
}
})();