在vue中用不同请求数据多次请求同一接口前端拿到的数据混乱或者拿不到数据

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

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值