axios请求频繁,如何取消上一次请求


前言

当事件中的代码执行耗费时间,且用户在短时间不断点击按钮,造成短时间多次触发了按钮的事件(不断向服务器发起请求)


在 vue 页面直接使用

代码如下(示例):

<script>
import axios from 'axios'
import qs from 'qs'
 
export default {
    
    
    methods: {
    
    
        request(keyword) {
    
    
            var CancelToken = axios.CancelToken
            var source = CancelToken.source()
              
            // 取消上一次请求
            this.cancelRequest();
            
            // 有的人可能会出现415 400的错误,415是因为没有设置对Content-Type 400是因为使用了qs.stringify(), 可以修改成JSON.stringify() 试试
            axios.post(url, qs.stringify({
    
    kw:keyword}), {
    
    
                headers: {
    
    
                    'Content-Type': 'application/x-www-form-urlencoded',
                    'Accept': 'application/json'
                },
                cancelToken: new axios.CancelToken(function executor(c) {
    
    
                    that.source = c;
                })
            }).then((res) => {
    
    
                // 在这里处理得到的数据
                ...
            }).catch((err) => {
    
    
                if (axios.isCancel(err)) {
    
    
                    console.log('Rquest canceled', err.message); //请求如果被取消,这里是返回取消的message
                } else {
    
    
                    //handle error
                    console.log(err);
                }
            })
        },
        cancelRequest(){
    
    
            if(typeof this.source ==='function'){
    
    
                this.source('终止请求')
            }
        },
    }
}
</script>

封装 utils 工具类

封装axios 请求,在响应拦截器中处理,结束上一次请求

步骤如下:

  • 定义一个Map用来存储发送请求的取消【函数】标识。
  • 在请求拦截器中,移出重复的请求【重复请求是指:方法 + 路径 + 入参 相同】。
  • 在请求拦截器中,发送请求前存储取消标识到Map中。
  • 在响应拦截器中,移出请求。

代码如下(示例):

import axios  from "axios";
let pendingMap = new Map();
 
/**
 * 取消正在发送的请求
 * @param {*} config 
 */
let removePending = function(config){
    
    
    var key = `${
      
      config.method}:${
      
      config.url}:${
      
      JSON.stringify(config.params)}`;
    var func = pendingMap.get(key);
    if(func){
    
    
        func();
        pendingMap.delete(key);
    }
}
 
// 创建axios实例
const baseURL = "/api";
const requests = axios.create({
    
    
    baseURL:baseURL,
    timeout:5000
});
 
//请求拦截器
requests.interceptors.request.use((config) =>{
    
    
    removePending(config);
    // config 中包含 headers 请求头
    config.headers.Authorization = `Bear ${
      
       sessionStorage.getItem("token")}`;
 
    // 发送请求,并将请求的取消标识放入pendingMap中
    config.cancelToken = new axios.CancelToken((cancelToken) => {
    
    
        pendingMap.set(`${
      
      config.method}:${
      
      config.url}:${
      
      JSON.stringify(config.params)}`,cancelToken)
    });
    return config;
});
 
//响应拦截器
requests.interceptors.response.use((res) => {
    
    
    // 请求成功移出请求
    removePending(res.config);
    return res.data;
},(error) => {
    
    
    return Promise.reject(error);
});
 
export default requests;

猜你喜欢

转载自blog.csdn.net/weixin_48353638/article/details/130123867