axios取消重复请求

1 篇文章 0 订阅

简言:
项目中经常会出现重复的请求,比如:一个提交按钮被测试一秒内狂暴点击n+1次!bug单瞬间降临,而且可能一口气提出n个可优化点。(黑人问号.jpg)其结果就是产生了相同请求n次,后台就出现了n次提交记录,当然着非我们想要的。还有就是有些方法要监听页面的滚动拉伸来触发某些指定的请求,这也会造成请求被触发n次。所以就可以引出今天的主角cancel token

首先:我们看一下axios的介绍说明

Axios 的 cancel token API 基于cancelable promises proposal,它还处于第一阶段。

可以使用 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();

接下来我们就要对其进行简单封装或者改造应用于我们的项目中
1、我们要解决的问题就对于重复的,一致的请求我们要对其进行取消

2、在哪里做?由于所有请求都会经过拦截器,那么我们就在拦截器中做这个

既然这两个确定了那么已经算是完成一半了

import axios from 'axios'

const api = axios.create({
  baseURL,
  headers: {
    'Content-Type': 'application/json;charset:UTF-8',
  },
})

// 参数处理
const paramsLink = params => {
  let urlStr = ''
  if (params && typeof params === 'object') {
    Object.keys(params).forEach(key => {
      const val = params[key]
        if (val || val == 0) {
       	  // 对参数进行连接(其实可以随意连接满足对比目的即可)
          urlStr += `#${key}=${val}`
        }
    })
  }
  return urlStr
}
// 存储所有的请求(为后续对比)
let pending = []
let cancelToken = axios.CancelToken
let cancelPending = config => {
  let params = config.data ? config.data : config.params
  if (
    pending.length > 1 &&
    pending[pending.length - 2].u === config.method + config.url + paramsLink(params)
  ) {
    pending[pending.length - 2].f() //取消上一次请求
    pending.splice(pending.length - 2, 1) //移除
  }
}
// 请求拦截器
api.interceptors.request.use(
  config => {
    config.cancelToken = new cancelToken(c => {
      let params = config.data ? config.data : config.params
      // 这里的axios标识用请求方法+请求地址+请求参数拼接的字符串
      pending.push({ u: config.method + config.url + paramsLink(params), f: c })
    })
    cancelPending(config)
    return config
  },
  error => {
    return Promise.reject(error)
  },
)
// 回馈拦截器
api.interceptors.response.use(
  response => {
    // 200/正常响应情况
    const resData = {
      ...response.data,
      code: response.data.code || errorStatus,
    }
    return resData
  },
  error => {
  	// 对error进行处理
    if (error == 'Cancel') return Promise.resolve(error)
 	// 接下来你可以做一些错误的处理
  },
)

好啦,基本处理过程都有展现如有疑问可以留言探讨

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值