Vue3+Typescript项目构建之封装axios并防止重复请求

1. 封装axios请求

utils文件夹下新建request.ts文件,专用于封装axios,对于使用vue2+js的开发者,封装axios并不难,看代码都看得懂。这里我主要想展示一下如何防止重复请求。

2. 防止重复请求

思路:把每次请求的url存到一个数组,循环判断当前url是否已经存在,如果存在就取消当前请求,如果不存在就存进去并正常执行请求。并且正常之后要把这次请求的url从数组里删除掉。要不然之后都无法再次请求该地址。

所以我们需要定义一个数组存放请求类别

const reqList: any[] = []

再分别定义一个停止请求函数和允许请求函数

/**
 * 阻止重复请求
 * @param {Array} reqList - 当前请求列表
 * @param {string} url - 当前请求地址
 * @param {function} cancel - 请求中断函数
 * @param {string} errorMessage - 请求中断是需提示的错误信息
 */
const handleStopRepeatRequest = (reqList: any[], url: any, cancel: any, errorMessage = ''):void => {
     
  for (let i = 0; i < reqList.length; i++) {
     
    if (reqList[i] === url) {
     
      cancel(errorMessage)
      return
    }
  }
  reqList.push(url)
}
/**
 * 允许某个请求可以继续进行
 * @param {array} reqList 全部请求列表
 * @param {string} url 请求地址
 */
const handleAllowRequest = (reqList: any[], url: any):void => {
     
  for (let i = 0; i < reqList.length; i++) {
     
    if (reqList[i] === url) {
     
      // 删除当前请求
      reqList.splice(i, 1)
      break
    }
  }
}

3. 完整代码

import axios from 'axios'
import {
      Toast } from 'vant'

const service = axios.create({
     
  baseURL: process.env.VUE_APP_BASE_URL,
  timeout: 10000,
  transformResponse: res => res
})

// 正在请求中的请求列表
const reqList: any[] = []

/**
 * 阻止重复请求
 * @param {Array} reqList - 当前请求列表
 * @param {string} url - 当前请求地址
 * @param {function} cancel - 请求中断函数
 * @param {string} errorMessage - 请求中断是需提示的错误信息
 */
const handleStopRepeatRequest = (reqList: any[], url: any, cancel: any, errorMessage = ''):void => {
     
  for (let i = 0; i < reqList.length; i++) {
     
    if (reqList[i] === url) {
     
      cancel(errorMessage)
      return
    }
  }
  reqList.push(url)
}
/**
 * 允许某个请求可以继续进行
 * @param {array} reqList 全部请求列表
 * @param {string} url 请求地址
 */
const handleAllowRequest = function(reqList: any[], url: any) {
     
  for (let i = 0; i < reqList.length; i++) {
     
    if (reqList[i] === url) {
     
      reqList.splice(i, 1)
      break
    }
  }
}

service.interceptors.request.use(config => {
     
  let cancel
  config.cancelToken = new axios.CancelToken(c => {
      cancel = c })

  // 阻止重复请求
  handleStopRepeatRequest(reqList, config.url, cancel, `${
       config.url} 正在请求中,请不要重复请求!`)

  return config
}, function(error) {
     
  return Promise.reject(error)
})

service.interceptors.response.use(res => {
     
  // 增加延迟,相同请求不得在短时间内重复发送
  setTimeout(() => {
     
    handleAllowRequest(reqList, res.config.url)
  }, 1000)

  // 这里可以针对后端返回的code做一些出错处理...

  return res.data
}, function(error) {
     
  if (axios.isCancel(error)) {
     
    console.log(error.message)
  } else {
     
    // 增加延迟,相同请求不得在短时间内重复发送
    setTimeout(() => {
     
      handleAllowRequest(reqList, error.config.url)
    }, 1000)
  }
  
  // 这里可以针对http status做一些出错处理~
  const {
      status } = error.response
  if (status === 404) {
     
    Toast.fail('抱歉,请求资源不存在!')
  } else if (status === 301) {
     
    Toast.fail('亲爱的,你还没登录哦!')
  }
  return Promise.reject(error)
})

export default service

你可能感兴趣的:(axios,axios重复请求,封装axios,vue3+typescript,typescript)