SOURCE

console 命令行工具 X clear

                    
>
console
// 缓存对象
let cache = {
    // 缓存列表
    list: [],
    // 最大缓存数
    MAX_NUM: 100,
    // 最大缓存时间
    EXPIRED_TIME: 60000,
    // 根据请求的信息(请求方式,url,请求get/post数据),产生map的key
    getRequestKey(config){
        const { method, url, params, data } = config;
        return [method, url, Qs.stringify(params), Qs.stringify(data)].join("&");
    },
    // 添加缓存结果
    add({config, data}){
        if(config.data) config.data = JSON.parse(config.data)
        let key = this.getRequestKey(config)
        let i = this.list.findIndex(t=>t.key === key)
        if(i>-1){
            // 保存请求结果
            this.list[i].data = data
            // 把结果给接口
            this.list[i].resolve(data)
        }else{
            // 添加到缓存列表中
            this.list.push({ time: Date.now(), key, data })
        }
    },
    // 查找缓存结果
    find(config){
        // 根据请求信息生成key
        let key = this.getRequestKey(config)
        let i = this.list.findIndex(t=>  t.key === key)
        // 判断缓存当中是否有该请求结果
        if(i>-1){
            let f = this.list[i]
            // 判断是否超出了最大缓存时间
            if(Date.now() - f.time > this.EXPIRED_TIME){
                // 清除该缓存
                this.list.splice(i, 1)
            }else{
                // 返回缓存
                return f
            }
        }
        // 添加缓存信息
        let t = {key, time: Date.now()}
        t.data = new Promise((resolve)=>{
            t.resolve = resolve
        })
        // 判断是否超出了最大缓存数量
        if(this.list.length === this.MAX_NUM){
            this.list.shift()
        }
        this.list.push(t)
        // 返回undefined,让请求拦截不执行config.adapter
        return undefined
    }
}   

let sendPost = function(data){
    return axios({
        url: 'http://nodejs-cloud-studio-demo-bkzxs.nodejs-cloud-studio-demo.50185620.cn-hangzhou.fc.devsapp.net/test',
        method: 'post',
        data
    })
}

axios.interceptors.request.use(async function (config) {
    let f =  cache.find(config)
    // 查看缓存当中有没有
    if(f){
        // 通过config.adapter,允许自定义处理请求
        config.adapter = function (config) {
            return new Promise((resolve) => {
                const res = {
                    status: 200,
                    statusText: 'OK',
                    headers: { 'content-type': 'application/json; charset=utf-8' },
                    config,
                    request: {}
                }
                // 判断缓存当中data是否是Promise?
                //   如果是,代表数据正在获取中
                //   如果不是代表请求已经获取过
                if(f.data instanceof Promise){
                    f.data.then(data=>{
                        resolve({ ...res, data })
                    })
                }else{
                    resolve({ ...res, data: f.data })
                }
            })
        }
    }
    return config
})
axios.interceptors.response.use(
  (response) => {
        //请求成功
        //缓存结果到缓存中
        cache.add(response)
        return response;
   }
);

new Vue({
    el: '#app',
    mounted() {
        this.$refs.btn1.click()
        this.$refs.btn2.click()
    },
    methods: {
        // 使用lodash对请求方法做防抖
        //这里有问题,只是对每个按钮的点击事件单独做了防抖,但是两个按钮之间做不到防抖的效果
        onClick1: async function(){
            let res = await sendPost({username:'zs', age: 20})
            console.log('请求1的结果', res.data)
        },
        onClick2: async function(){
            let res = await sendPost({username:'zs', age: 20})
            console.log('请求2的结果', res.data)
        },
    },
})
    <div id="app">
        <button @click="onClick1" ref="btn1">请求1</button>
        <button @click="onClick2" ref="btn2">请求2</button>
    </div>

本项目引用的自定义外部资源