首先这里描述一下问题
vue项目不同路由使用同一组件,当这些路由切换的时候改变请求参数,但是统一接口。这样可能因为响应时间的问题造成a页面切到b页面再切回a页面,此时显示的是b页面的数据。造成这样的原因是接口返回时间的问题。所以就想到用axiso的cancelToken方法去cancel在pengidng的请求。
- 实现方式一:全局的修改
import axios from 'axios';
let pending = []; //声明一个数组用于存储每个ajax请求的取消函数和ajax标识
let cancelToken = axios.CancelToken;
let cancelPending = (pe) => { for(let p in pending){
//当当前请求在数组中存在时执行函数体
if(pending[p].u === pe.url + '&' + pe.method) {
pending[p].f(); //执行取消操作
pending.splice(p, 1); //把这条记录从数组中移除
}
}
}
//http request 拦截器
axios.interceptors.request.use(
config => {
// -------------------------------------------------------------
cancelPending(config); //在一个ajax发送前执行一下取消操作
config.cancelToken = new cancelToken((c)=>{
// 这里的ajax标识我是用请求地址&请求方式拼接的字符串,当然你可以选择其他的一些方式
pending.push({ u: config.url + '&' + config.method, f: c });
});
// ------------------------------------------------------------------
return config;
},
error => {
return Promise.reject(err);
}
);
//http response 拦截器
axios.interceptors.response.use(
response => {
//-----------------------------------
//在一个ajax响应后再执行一下取消操作,把已经完成的请求从pending中移除
cancelPending(res.config);
//-------------------------
return response;
},
error => {
//这段不加报错
if (axios.isCancel(error)) { //判断是否取消了请求 return Promise.reject(error); } return Promise.reject(error)
}
)- 方法二:局部修改
/**request.js**/import { request } from "../request";import axios from "axios";
export function getEventList(params, _this) { // 解决多次重复发送同一请求造成数据混乱 const CancelToken = axios.CancelToken; return request({ method: "GET", url: "***", params: { ...params }, cancelToken: new CancelToken(function executor(c) { _this.cancelAjax = c; }) });}/****/
if (typeof this.cancelAjax === "function") { this.cancelAjax(); }getEventList(this.searchParams, this) .then(res => { if (res.data) { ..... }) .catch(err => { console.log(err); });
这样就可以解决问题了,不过这种问题好像比较不常见,用放重复点击或者loading,都可以避免这个问题。可是我们业务有这个需求,所以难受。
方法不一定很好用,如果大神有什么好的方法,或者有什么错误的地方,欢迎批评指正。谢谢!