Vue路由切换 & Axios接口取消重复请求

在日常前端开发中, 经常会遇到频繁发起的重复请求, 会给服务器及网络造成不必要的压力, 可通过取消重复请求解决

场景

订单数据条件筛选查询

表单提交按钮频繁点击

路由页面切换请求未取消

解决方案:

在每个请求发起的时候存储当前存储的标记在一个数组或Map中, 针对每个请求(或者特定的请求,可以通过在请求头中加字段)的时候在请求拦截中查询是否重复, 如果已重复则取消历史中重复的请求, 再发起当前请求, 如果没有重复, 则添加存储标记并正常请求, 已请求完成的清除存储标记。

axios中如何取消请求

1、可以使用 CancelToken.source 工厂方法创建 cancel token,像这样:

javascript 复制代码
const CancelToken = axios.CancelToken;
const source = CancelToken.source();
 
axios.get('/user/12345', {
  cancelToken: source.token
}).catch(function(thrown) {
  if (axios.isCancel(thrown)) {
    console.log('Request canceled', thrown.message);
  } else {
     // 处理错误
  }
});
 
axios.post('/user/12345', {
  name: 'new name'
}, {
  cancelToken: source.token
})
 
// 取消请求(message 参数是可选的)
source.cancel('Operation canceled by the user.');

还可以通过传递一个 executor 函数到 CancelToken 的构造函数来创建 cancel token:

javascript 复制代码
const CancelToken = axios.CancelToken;
let cancel;
 
axios.get('/user/12345', {
  cancelToken: new CancelToken(function executor(c) {
    // executor 函数接收一个 cancel 函数作为参数
    cancel = c;
  })
});
 
// cancel the request
cancel();

项目中封装使用。

javascript 复制代码
const pendingXHRMap = new Map();

/**
 * 添加请求
 * @param {Object} config
 */
export const addPendingXHR = (config) => {
  const url = [
    config.method,
    config.url
  ].join("&");
  config.cancelToken = config.cancelToken || new axios.CancelToken(cancel => {
    if (!pendingXHRMap.has(url)) { // 如果 pending 中不存在当前请求,则添加进去
      pendingXHRMap .set(url, cancel);
    }
  });
};

// 删除请求记录
/**
 * 移除请求
 * @param {Object} config;
 */
export const removePendingXHR = (config) => {
  const url = [
    config.method,
    config.url
  ].join("&");
  if (pendingXHRMap.has(url)) { // 如果在 pending 中存在当前请求标识,需要取消当前 请求,并且移除
    const cancel = pendingXHRMap.get(url);
    cancel(url);
    pendingXHRMap .delete(url);
  }
};

axios中使用:

javascript 复制代码
// 请求拦截处理
axios.interceptors.request.use(config => {
    // 这里根据自定义的请求头进行判断
    removePendingXHR(config)
    addPendingXHR(config)
    ...
    return config
})
 
// 响应拦截处理
axios.interceptors.response.use(response => {
    removePendingXHR(response)
    ...
}, error => {
})

Vue中当路由切换页面的时候,将上一个页面的所有请求取消。

javascript 复制代码
router.beforeEach((to, from, next) => {
    // 遍历pendingMap,将上一个页面的所有请求cancel掉
    pendingXHRMap.forEach((cancel) => {
        cancel();
    });
    pendingXHRMap.clear()
})
相关推荐
Dontla2 小时前
为什么React列表项需要key?(React key)(稳定的唯一标识key有助于React虚拟DOM优化重绘大型列表)
javascript·react.js·ecmascript
EndingCoder3 小时前
React从基础入门到高级实战:React 实战项目 - 项目三:实时聊天应用
前端·react.js·架构·前端框架
阿阳微客5 小时前
Steam 搬砖项目深度拆解:从抵触到真香的转型之路
前端·笔记·学习·游戏
德育处主任Pro5 小时前
『React』Fragment的用法及简写形式
前端·javascript·react.js
CodeBlossom5 小时前
javaweb -html -CSS
前端·javascript·html
CodeCraft Studio5 小时前
【案例分享】如何借助JS UI组件库DHTMLX Suite构建高效物联网IIoT平台
javascript·物联网·ui
打小就很皮...6 小时前
HBuilder 发行Android(apk包)全流程指南
前端·javascript·微信小程序
集成显卡7 小时前
PlayWright | 初识微软出品的 WEB 应用自动化测试框架
前端·chrome·测试工具·microsoft·自动化·edge浏览器
前端小趴菜058 小时前
React - 组件通信
前端·react.js·前端框架
Amy_cx8 小时前
在表单输入框按回车页面刷新的问题
前端·elementui