我在项目中遇到这样一个问题:javascript
在Angular项目中,会有不少须要用户点击操做的地方,若是用户点击过快会产生屡次相同请求,会吃服务器带宽,若是这是其余涉及钱有关的操做,这会产生一个致命的问题。对于这个问题,我想到了两种解决方案: html
1. 好比 在点击一个按钮操做的时候,咱们经过将这个按钮 disabled 属性设置为 true
,当请求结束后,再设置为 false ,前端
代码: java
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; }) }
若是我有不少这样的操做,就须要写不少相同的代码。url
AngularJs提供了一个拦截器,每次请求在http时,会先到拦截器中。因此,咱们能够在拦截器中采起处理:spa
1.首先定义一个参数如:is_click, 在须要处理这个操做的地方经过附加这个参数,这样可让咱们去判断这个操做需不须要去检测code
2.若是有,则进行检测,是否在一秒以内有相同请求(method、url、参数全相同视为相同请求)htm
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; } };
总结:
做为前端小学生,第一次写文章,难免有些错误的地方,但愿你们能够提出来,感谢。