問題前述
我在項目中遇到這樣一個問題:
在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; } };
總結:
作為前端小學生,第一次寫文章,不免有些錯誤的地方,希望大家可以提出來,感謝。