问题前述
我在项目中遇到这样一个问题:
在Angular项目中,会有很多需要用户点击操作的地方,如果用户点击过快会产生多次相同请求,会吃服务器带宽,如果这是其他涉及钱有关的操作,这会产生一个致命的问题。对于这个问题,我想到了两种解决方案:
1. 比如 在点击一个按钮操作的时候,我们通过将这个按钮 disabled 属性设置为 true
,当请求结束后,再设置为 false ,
代码:
html:
<div class="btn" ng-click="login()" ng-disabled="is_click">登录</div>
Js:
$scope.login = function(){
//将按钮置为不可点击状态
is_click = true; //执行http请求操作
$http({
method : method,
params : params,
url : Config.BASE_URL + url
})
.then(function(){
//请求成功,将按钮置为可点击状态
is_click = false;
})
}
如果我有很多这样的操作,就需要写很多相同的代码。
AngularJs提供了一个拦截器,每次请求在http时,会先到拦截器中。所以,我们可以在拦截器中采取处理:
1.首先定义一个参数如:is_click, 在需要处理这个操作的地方通过附加这个参数,这样可以让我们去判断这个操作需不需要去检测
2.如果有,则进行检测,是否在一秒之内有相同请求(method、url、参数全相同视为相同请求)
3.如果没有,则添加到缓存中,如果有,则取消操作
具体见代码:
.factory('interceptor', ['$scope', function($scope){
var requestList = []; //缓存记录
function addRequestList(url){ //插入记录
var keepGoing = true;
angular.forEach(requestList, function (item) {
if(keepGoing && item.name == url){
item.time = new Date().getTime();
keepGoing = false;
}
}); if(keepGoing){
requestList.push({
name: url,
time: new Date().getTime()
});
}
}
function hitRequestList(url) { //检测是否有记录,并返回时间
var time = '';
var keepGoing = true;
angular.forEach(requestList, function (item) {
if(keepGoing && item.name == url){
time = item.time;
keepGoing = false;
}
});
return time;
}
//method,url,data 拼接成 string
function getRequestKey(data) {
var key = 'method:' + data.method + ',url:' + data.url + ',data:';
var str = ''; //特殊处理
... return key += str ? str : JSON.stringify(data.params || {});
}
var _interceptor = {
'request': function(req) {
if (req.params && req.params.is_click) {
var key = getRequestKey(req);
var lastTime = hitRequestList(key); //上次请求时间
var requesTime = new Date().getTime(); //当前请求时间
if (lastTime && ((requesTime - lastTime) < 1000)) {
console.log('----------', '取消这次请求');
req.method = 'GET';
req.cache = {
get: function () {
return null;
}
};
}
addRequestList(key);
}
return _interceptor
}])
最主要的取消请求的代码:
req.method = 'GET';
req.cache = {
get: function () {
return null;
}
}; 总结:
作为前端小学生,第一次写文章,不免有些错误的地方,希望大家可以提出来,感谢。