實現axios限制請求隊列

背景是:前端

在實際開發中,可能會遇到網絡問題或者查詢量比較大的狀況,上一個請求尚未完成,用戶就發起了下一個請求。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

相關文章
相關標籤/搜索