Vue路由切换和Axios接口取消重复请求详解

作者:南城大前端 时间:2024-04-30 10:28:17 

前言

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

场景

  • 订单数据条件筛选查询

  • 表单提交按钮频繁点击

  • 路由页面切换请求未取消

解决方案

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

axios中如何取消请求

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

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:

const CancelToken = axios.CancelToken;
let cancel;

axios.get('/user/12345', {
 cancelToken: new CancelToken(function executor(c) {
   // executor 函数接收一个 cancel 函数作为参数
   cancel = c;
 })
});

// cancel the request
cancel();

项目中封装使用

基本变量定义

// 是否取消重复请求开关
const cancelDuplicated = true

// 存储每个请求中的map
const pendingXHRMap = new Map()

// 取消请求类型定义 便于后期对此类型不做异常处理
const REQUEST_TYPE = {
 DUPLICATED_REQUEST: 'duplicatedRequest'
}

设置重复标记的函数

const duplicatedKeyFn = (config) => {
 // 可在此设置用户自定义其他唯一标识 默认按请求方式 + 请求地址
 return `${config.method}${config.url}`
}

添加到请求记录

const addPendingXHR = (config) => {
 if (!cancelDuplicated) {
   return
 }
 const duplicatedKey = JSON.stringify({
   duplicatedKey: duplicatedKeyFn(config),
   type: REQUEST_TYPE.DUPLICATED_REQUEST
 })
 config.cancelToken = config.cancelToken || new axios.CancelToken((cancel) => {
   if (duplicatedKey && !pendingXHRMap.has(duplicatedKey)) {
     pendingXHRMap.set(duplicatedKey, cancel)
   }
 })
}

删除请求记录

const removePendingXHR = (config) => {
 if (!cancelDuplicated) {
   return
 }
 const duplicatedKey = JSON.stringify({
   duplicatedKey: duplicatedKeyFn(config),
   type: REQUEST_TYPE.DUPLICATED_REQUEST
 })
 if (duplicatedKey && pendingXHRMap.has(duplicatedKey)) {
   const cancel = pendingXHRMap.get(duplicatedKey)
   cancel(duplicatedKey)
   pendingXHRMap.delete(duplicatedKey)
 }
}

axios中使用

// 请求拦截处理
axios.interceptors.request.use(config => {
   removePendingXHR(config)
   addPendingXHR(config)
   ...
   return config
})

// 响应拦截处理
axios.interceptors.response.use(response => {
   removePendingXHR(response.config)
   ...
}, error => {
   // 如果是取消请求类型则忽略异常处理
   let isDuplicatedType;
   try {
     const errorType = (JSON.parse(error.message) || {}).type
     isDuplicatedType = errorType === REQUEST_TYPE.DUPLICATED_REQUEST;
   } catch (error) {
     isDuplicatedType = false
   }
   if (!isDuplicatedType) {
       // 其他异常处理
   }
})

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

router.beforeEach((to, from, next) => {
   // 遍历pendingMap,将上一个页面的所有请求cancel掉
   pendingXHRMap.forEach((cancel) => {
       cancel();
   });
   pendingXHRMap.clear()
})

来源:https://segmentfault.com/a/1190000041774311

标签:axios,重复,请求
0
投稿

猜你喜欢

  • PHP实现的DES加密解密类定义与用法示例

    2023-07-17 08:55:54
  • SQL Server修改表所有者

    2010-02-04 08:33:00
  • python中关于对super()函数疑问解惑

    2022-08-10 04:11:48
  • logrus hook输出日志到本地磁盘的操作

    2024-04-26 17:34:47
  • Go语言学习之Switch语句的使用

    2024-04-23 09:38:57
  • Python实现七大查找算法的示例代码

    2021-05-28 07:33:35
  • python实现拓扑排序的基本教程

    2021-03-24 04:24:02
  • python字典DICT类型合并详解

    2023-01-03 07:37:12
  • 分享五个超实用Python脚本,减少垃圾软件负担

    2022-07-18 18:38:59
  • Python数据相关系数矩阵和热力图轻松实现教程

    2022-06-08 05:12:06
  • MySQL获得当前日期时间函数示例详解

    2024-01-27 07:54:48
  • PHP实现无限极分类的两种方式示例【递归和引用方式】

    2023-11-15 18:26:33
  • SQL Server提示"选定的用户拥有对象,所以无法除去该用户”

    2024-01-22 03:35:05
  • Python 错误和异常代码详解

    2022-02-12 15:14:08
  • MySQL 8.0新功能监控统计限制连接不再担心被垃圾SQL搞爆内存

    2024-01-16 12:51:25
  • python关键字传递参数实例分析

    2023-08-24 04:28:34
  • Django组件content-type使用方法详解

    2023-10-01 13:54:42
  • Python enumerate索引迭代代码解析

    2022-04-05 17:13:07
  • Python Pyecharts绘制箱线图详解

    2021-03-31 05:57:05
  • python妙用之编码的转换详解

    2022-01-29 05:01:54
  • asp之家 网络编程 m.aspxhome.com