zl程序教程

您现在的位置是:首页 >  其他

当前栏目

axios全局做节流,解决多次点击导致多次请求接口

接口 解决 请求 点击 导致 全局 Axios 多次
2023-09-27 14:22:47 时间

axios全局做节流,解决多次点击导致多次请求接口

1、收集请求的接口
2、判断当前接口上次请求时间
3、过滤过期判断的接口

收集请求的接口并判断是否可以继续请求

let reqList = []
// 默认maxTime 节流操作目的是为了方式用户手滑点击多次新增或者修改
let maxTime = 500
// 过滤请求事件
const stopRepeatRequest = (url, cancelFun) => {
    // url存在  更新 time
    if (reqList.length !== 0 && reqList.find(i => i.url === url)) {
        // 存在
        // 存在 并且 还不能进行下次点击
        let arr = reqList.filter(item => item.url === url && new Date().getTime() - item.time < maxTime)
        if (arr && arr.length !== 0) {
            cancelFun()
            return true
        } else {
            // 存在能进行下一次点击  能进行接口连接
            reqList = reqList.map(i => {
                if (i.url === url) {
                    i.time = new Date().getTime()
                }
                return i
            })
            return false
        }
    } else {
        // 不存在直接添加 能进行接口连接
        reqList.push({
            url,
            time: new Date().getTime()
        })
        return false
    }
}

过滤过期判断的接口

// 接口请求完成后清除
const allowRequest = () => {
    if (reqList.length) {
        // 只保留不能多次请求的接口
        reqList = reqList.filter(item => new Date().getTime() - item.time < maxTime)
    }
}
// 响应拦截
Ajax.interceptors.response.use(response => {
    // Do something before response is sent
    allowRequest()
    return response;
}, error => {
    // Do something with response error
    return Promise.reject(error);
});

全部代码

/*
 * @Descripttion: 
 * @version: 
 * @Author: ZhangJunQing
 * @Date: 2022-05-23 11:46:01
 * @LastEditors: ZhangJunQing
 * @LastEditTime: 2022-08-30 14:41:25
 */
import axios from 'axios';
import context from '@/main.js'
import { baseURL } from '@/Url'
let reqList = []
// 默认maxTime 节流操作目的是为了方式用户手滑点击多次新增或者修改
let maxTime = 500
const Ajax = axios.create({
    // 是否携带cookie
    withCredentials: true,
    baseURL,
    timeout: 50000
})
// 过滤请求事件
const stopRepeatRequest = (url, cancelFun) => {
    // 过滤可以多次一直请求的接口
    // 情况包括整个页面调用了两次整个接口 
    const filterList =[
        // 动态查询、展示列模板接口
        '/temp/query'
    ]
    if(filterList.includes(url)){
        return false
    }
    // url存在  更新 time
    if (reqList.length !== 0 && reqList.find(i => i.url === url)) {
        // 存在
        // 存在 并且 还不能进行下次点击
        let arr = reqList.filter(item => item.url === url && new Date().getTime() - item.time < maxTime)
        if (arr && arr.length !== 0) {
            cancelFun()
            return true
        } else {
            // 存在能进行下一次点击  能进行接口连接
            reqList = reqList.map(i => {
                if (i.url === url) {
                    i.time = new Date().getTime()
                }
                return i
            })
            return false
        }
    } else {
        // 不存在直接添加 能进行接口连接
        reqList.push({
            url,
            time: new Date().getTime()
        })
        return false
    }
}
// 接口请求完成后清除
const allowRequest = () => {
    if (reqList.length) {
        // 只保留不能多次请求的接口
        reqList = reqList.filter(item => new Date().getTime() - item.time < maxTime)
    }
}
// 请求拦截
Ajax.interceptors.request.use(config => {
    // 增加请求头
    config.headers["token"] = "631858809502165102"
    config.headers["authCode"] = "000001"
    config.headers["sysCode"] = "100003"
    let cancelFun = null
    config.cancelToken = new axios.CancelToken(cancel => {
        cancelFun = cancel
    })
    stopRepeatRequest(config.url, cancelFun)
    return config;
}, error => {
    // Do something with request error
    return Promise.reject(error);
});
// 响应拦截
Ajax.interceptors.response.use(response => {
    // Do something before response is sent
    allowRequest()
    return response;
}, error => {
    // Do something with response error
    return Promise.reject(error);
});

const returnNewPro = (promise) => promise.then(res => {
    // console.log(promise.config.responseType, 'promisepromisepromise')
    if (promise.config && promise.config.responseType === 'arraybuffer') {
        return [null, res]
    }
    const resData = res.data;
    // context.$message.success('请求成功')
    return [null, resData]
}).catch(err => {
    console.log(err, 'promisepromisepromise')
    // code: "ERR_CANCELED"
    // message: "canceled"
    // name: "CanceledError"
    // stack: ""
    if (err.name === 'CanceledError') {
        console.log('多次请求接口------')
        // context.$message.info('让接口歇一会')
    } else {
        context.$message.error("接口请求失败");
    }
    return [err, null]
})

export const get = async (url, params, headers = {}) => {
    return await returnNewPro(Ajax.get(url, { params, headers }))
}
/**
 * 
 * @param {*} url 
 * @param {*} params 
 * @param {*} headers 
 * @returns [] 
 */
export const post = (url, params, headers = {}) => {
    return returnNewPro(Ajax.post(url, params, headers))
}