背景是:前端
在實際開發中,可能會遇到網絡問題或者查詢量比較大的狀況,上一個請求尚未完成,用戶就發起了下一個請求。ios
會形成什麼狀況呢?axios
可是同一個請求屢次發送到服務器,無疑是對服務器的一種壓力,因此須要在已經優化服務器過查詢速度後,以及用戶網絡狀況比較差的條件下,在前端進行請求限制。api
axios
自帶的cancelToken能夠幫咱們實現這個需求,而且提供給了咱們一個現成的api axios.CancelToken
,這是一個返回值是帶有請求信息的回調函數,咱們能夠在須要cancel的時候去執行這個回調函數。具體實現以下:服務器
const service = axios.create({});
const pendingMap = new Map();
const addPending = (config) => {
config.cancelToken = config.cancelToken || new axios.CancelToken(cancel => {
if(!pendingMap.has(config.url)){
pendingMap.set(config.url,cancel);
}
})
}
const removePending = (config) => {
if(pendingMap.has(config.url)){
let cancel = pendingMap.get(config.url);
cancel(config.url);
pendingMap.delete(config.url)
}
}
複製代碼
本地維護一個Map來存儲每一個請求信息, addPending
中每次會去先判斷是否有cancelToken,若是有就不用從新建立一個cancelToken。 removePending
中判斷請求信息是否在Map中,若是該請求存在於Map中,則執行cancel函數,並刪除Map中的該請求。markdown
攔截器中的具體應用:網絡
service.interceptors.request.use(config => {
removePending(config) // 若是存在Map中先cancel該請求
addPending(config) // 添加該請求到Map中
return config
})
service.interceptors.response.use(response => {
``` // some code
return response.data
},error => {
// 捕獲cancel請求並拋出
if(error instanceof Cancel){
error.message = '上一請求還沒有結束,稍等~';
Message.error(error.message);
return Promise.reject(error.response)
// 這裏拋出須要注意,在請求時調用try-catch進行捕獲
})
)
複製代碼
這裏攔截成功後,就能夠限制住大流量的屢次請求。函數
這裏只是一個例子,也能夠經過判斷按鈕邏輯來控制用戶是否發起請求。優化
若是有補充或者錯誤的,請不吝指點~url