vue项目路由跳转后上一页面未完成的接口取消
一、 需求
在路由跳转后,如果上一个页面未完成的接口请求,需要取消掉。
比如: 页面A请求接口A,页面B请求接口B。从页面A跳转到页面B,如果接口A未完成,需要取消掉(尤其是点击过快的情况下,还会出现本地缓存的参数被新页面参数替换的情况)。
二、 实现思路
两种方法可以实现:
1. 使用 cancelToken 取消请求
2. 使用内置的 AbortController 取消请求
两种方法思路基本一致,只是代码编辑方面有点不同;在axios的请求拦截器中收集所有发送的接口,存储在vuex的一个数组中,然后在router.beforeEach中(或点击事件中)监听到路由跳转,就把该数组中的所有未完成的请求取消。
三、 代码实现
1. 在store中创建添加请求到数组中,和把数组中请求清空的方法
const state = {
clearPmsArr: [], // 取消请求方法数组
};
const mutations = {
pushPmsStack(state, payload) {
state.clearPmsArr.push(payload.clearPms);
},
clearPmsStack({ clearPmsArr }) {
clearPmsArr.forEach((item) => {
// 使用 cancelToken 取消请求
// item("路由跳转取消之前页面请求请求");
// 使用内置的 AbortController 取消请求
item.abort("路由跳转取消之前页面请求请求")
});
clearPmsArr = [];
},
};
export default {
namespaced: true,
state,
mutations,
};
2. 在axios的请求拦截器中收集发送的请求,调用store的方法;存入对应需要取消的请求方法;在响应拦截器拦截下来 不抛出错误
// 公司将 Axios 进行了一次封装 自己在请求和响应拦截中写上就好
class HttpService extends HttpLib {
// 请求拦截器
requestBefore(config) {
config = {
...config,
}
// 使用 cancelToken 取消请求
// store.commit("pmsStack/pushPmsStack", { clearPms: super.cancel });
// 使用内置的 AbortController 取消请求
const controller = new AbortController();
config.signal = controller.signal;
// 存入取消请求的 函数;用于切换页面时取消请求
store.commit("pmsStck/pushPmsStack", { clearPms: controller });
// ...代码省略
return super.requestBefore(config)
}
// 在响应拦截器拦截下来 不抛出错误
responseFailed(error) {
if(error.name && error.name === "CanceledError"){
// 取消请求的情况下,终端Promise调用链
return new Promise(() => {});
}
return new Promise((resolve, reject) => {
super.responseFailed(error).catch((e) => {
...
})
})
}
}
3. 在路由跳转前(或方法中)取消请求
store.commit("pmsStack/clearPmsStack")