在vue中用不同请求数据多次请求同一接口前端拿到的数据混乱或者拿不到数据
el-radio-button切换不同的按钮获取到列表的数据不同,多次快速切换偶尔发现显示的数据混乱,解决:添加定时器:data(){return {timer: null,//定时器}},methods: {//获取列表数据search (data) {clearTimeout(this.timer); //清除没执行的timer定时器this.timer = setTimeout(() =&
·
el-radio-button切换不同的按钮获取到列表的数据不同,多次快速切换偶尔发现显示的数据混乱
场景:
用户快速切换Tab,由于网络延迟等原因,造成数据混乱,很可能最后停留的Tab所展示的内容,并不是用户想要看到的内容.
原理:
多个异步操作同时竞争资源或者执行时造成的竞态
解决办法:
1,通过取消请求实现(切换的时候发现上个还在请求,就直接取消请求)
1.1, Fetch API abortController
const axios = require('axios');
const controller = new AbortController();
const signal = controller.signal;
axios.get('https://your-api.com/data', {
signal,
}).then(response => {
console.log(response.data);
}).catch(error => {
console.log('AbortController error:', error.message);
if (axios.isCancel(error)) {
console.log('Request canceled:', error.message);
} else {
// handle non-cancel errors
}
});
controller.abort();
1.2, Axios cancelToken(但是cancelToken 从 v0.22.0 开始已被 axios 弃用。原因是基于实现该 API 的提案 cancelable promises proposal 已被撤销。)
const CancelToken = axios.CancelToken;
const source = CancelToken.source();
axios.get('/someApi', {
cancelToken: source.token
}).catch(function(thrown) {
if (axios.isCancel(thrown)) {
console.log('Request canceled', thrown.message);
} else {
// 处理错误
}
});
// 取消请求(可以在任何时候调用)
source.cancel('Operation canceled by the user.');
1.3, XMLHttpRequest 取消请求
xhr.abort()
2,通过忽略请求实现(忽略了请求之后的赋值操作)
2.1, 可以基于指令式 promise 封装一个自动忽略过期请求的高阶函数 onlyResolvesLast。在每次发送新请求前,cancel 掉上一次的请求,忽略它的回调。
function onlyResolvesLast(fn) {
// 保存上一个请求的 cancel 方法
let cancelPrevious = null;
const wrappedFn = (...args) => {
// 当前请求执行前,先 cancel 上一个请求
cancelPrevious && cancelPrevious();
// 执行当前请求
const result = fn.apply(this, args);
// 创建指令式的 promise,暴露 cancel 方法并保存
const { promise, cancel } = createImperativePromise(result);
cancelPrevious = cancel;
return promise;
};
return wrappedFn;
}
2.2, 使用队列
与使用锁类似,我们把每个请求都放进队列里,对每次返回的请求进行判断,如果这个请求不是最新的请求,那么就忽略掉
3,通过禁用页面(如果数据没有请求完成就禁止点另外的tab)
可以配合使用loading
更多推荐
已为社区贡献2条内容
所有评论(0)