先說下我的需求,我們項目的要做的是如果有一個a請求進來,如果在這個a請求服務端沒有給響應,則後續的a請求再次進來的時候,直接return出來,不會請求
這裏有參考這篇文章 取消axios請求
但是這個是取消之前的請求,而不是攔截後面的請求,不符合我們項目的要求,所以,自己就改了這樣
因爲我們項目裏面是使用的axios,所以已aixos爲例
import axios from "axios";
// 序列化參數
const paramsStr = params => {
let str = "";
if (typeof params === "object" && typeof params !== null) {
Object.keys(params).forEach(key => {
const element = params[key];
if (element || element == 0) {
if (str) {
str+= `&${key}=${element}`;
} else {
str+= `?${key}=${element}`;
}
}
});
}
return str;
};
// 存儲所有的請求
let request = [];
// 刪除請求
const removeReuest = (url, data) => {
request.forEach((item, index) => {
if (item=== `${url}${data}`) {
request.splice(index, 1);
}
});
};
axios.interceptors.request.use(
function(config) {
// 請求進來的時候,查詢request裏面是否已經存在當前請求,如果查詢到,直接return掉這個請求
const flag = request.find(
item => item=== `${config.url}${paramsStr(config.data)}`
);
if (flag) {
return Promise.reject("cancel");
}
// 否則把數據推入request,儲存當前請求 這裏使用url和序列化參數組成唯一標識(可以改成自己的需要的)
request.push(`${config.url}${paramsStr(config.data)}`);
return config;
},
function(error) {
// 對請求錯誤做些什麼
return Promise.reject(error);
}
);
// 添加響應攔截器
axios.interceptors.response.use(
function(response) {
// 服務器響應,則刪除之前的請求
removeReuest(
response.config.url,
paramsStr(JSON.parse(response.config.data || "{}"))
);
// 對響應數據做點什麼
return response;
},
function(error) {
// 如果message不等於cancel,說明是服務器拋出的異常,
// 則要刪除數組的最後一位請求,因爲所有的請求服務器響應失敗,都會走到這裏,所以在這裏刪除,如果不刪除的
// 後續的請求再次進來,會被直接攔截,所以要在這裏刪除之前的請求
// 如果等於cancel則不用刪除,因爲數據沒有推入request這個請求
if (error.message !== "cancel") {
request.pop();
}
// 對響應錯誤做點什麼
return Promise.reject(error);
}
);