日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網為廣大站長提供免費收錄網站服務,提交前請做好本站友鏈:【 網站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

概述

  • 屬于專欄-項目難點
  • 重要程度:★★★★☆

背景

項目當中前端代碼會遇到同一個請求向服務器發了多次的情況,我們要避免服務器資源浪費,同一個請求一定時間只允許發一次請求

思路

(1)如果業務簡單,例如同一個按鈕防止多次點擊,我們可以用定時器做防抖處理 (2)如果業務復雜,例如多個組件通過代碼,同一個請求發多次,這個時候防抖已經不好處理了,最好是對重復的ajax請求統一做取消操作

實現

方式1-通過定時器做防抖處理

(a)概述

效果:當用戶連續點擊多次同一個按鈕,最后一次點擊之后,過小段時間后才發起一次請求 原理:每次調用方法后都產生一個定時器,定時器結束以后再發請求,如果重復調用方法,就取消當前的定時器,創建新的定時器,等結束后再發請求,工作當中可以用第三方封裝的工具函數例如lodash的debounce方法來簡化防抖的代碼

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="https://lf26-cdn-tos.bytecdntp.com/cdn/expire-1-M/lodash.js/4.17.21/lodash.min.js" type="Application/JAVAscript"></script>
    <script src="https://lf26-cdn-tos.bytecdntp.com/cdn/expire-1-M/vue/2.6.14/vue.min.js" type="application/JavaScript"></script>
    <script src="https://lf9-cdn-tos.bytecdntp.com/cdn/expire-1-M/axIOS/0.26.0/axios.min.js" type="application/javascript"></script>
</head>
<body>
    <div id="app">
        <button @click="onClick">請求</button>
    </div>
</body>
<script>
// 定義請求接口
function sendPost(data){
    return axios({
        url: 'https://nodejs-cloud-studio-demo-bkzxs.nodejs-cloud-studio-demo.50185620.cn-hangzhou.fc.devsapp.NET/test',
        method: 'post',
        data
    })
}
new Vue({
    el: '#app',
    methods: {
        // 調用lodash的防抖方法debounce,實現連續點擊按鈕多次,0.3秒后調用1次接口
        onClick: _.debounce(async function(){
            let res = awAIt sendPost({username:'zs', age: 20})
            console.log('請求的結果', res.data)
        }, 300),
    },
})
</script>
</html>

(c)預覽

連接

(d)存在的問題

無法解決多個按鈕件的重復請求的發送問題,例如下面兩種情況

情況-在點擊事件上做防抖

按鈕事件間是相互獨立的,調用的是不同方法,做不到按鈕間防抖效果

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="https://lf26-cdn-tos.bytecdntp.com/cdn/expire-1-M/lodash.js/4.17.21/lodash.min.js" type="application/javascript"></script>
    <script src="https://lf26-cdn-tos.bytecdntp.com/cdn/expire-1-M/vue/2.6.14/vue.min.js" type="application/javascript"></script>
    <script src="https://lf9-cdn-tos.bytecdntp.com/cdn/expire-1-M/axios/0.26.0/axios.min.js" type="application/javascript"></script>
</head>
<body>
    <div id="app">
        <button @click="onClick1" ref="btn1">請求1</button>
        <button @click="onClick2" ref="btn2">請求2</button>
    </div>
</body>
<script>
  
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
    })
}
new Vue({
    el: '#app',
    mounted() {
        this.$refs.btn1.click()
        this.$refs.btn2.click()
    },
    methods: {
        // 使用lodash對請求方法做防抖
        //這里有問題,只是對每個按鈕的點擊事件單獨做了防抖,但是兩個按鈕之間做不到防抖的效果
        onClick1: _.debounce(async function(){
            let res = await sendPost({username:'zs', age: 20})
            console.log('請求1的結果', res.data)
        }, 300),
        onClick2: _.debounce(async function(){
            let res = await sendPost({username:'zs', age: 20})
            console.log('請求2的結果', res.data)
        }, 300),
    },
})
</script>
</html>

情況2-在接口方法做防抖

按鈕間調用的方法是相同的,是可以對方法做防抖處理,但是處理本身對方法做了一次封裝,會影響到之前方法的返回值接收,需要對之前的方法做更多處理,變得更加復雜,不推薦

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="https://lf26-cdn-tos.bytecdntp.com/cdn/expire-1-M/lodash.js/4.17.21/lodash.min.js" type="application/javascript"></script>
    <script src="https://lf26-cdn-tos.bytecdntp.com/cdn/expire-1-M/vue/2.6.14/vue.min.js" type="application/javascript"></script>
    <script src="https://lf9-cdn-tos.bytecdntp.com/cdn/expire-1-M/axios/0.26.0/axios.min.js" type="application/javascript"></script>
</head>
<body>
    <div id="app">
        <button @click="onClick1" ref="btn1">請求1</button>
        <button @click="onClick2" ref="btn2">請求2</button>
    </div>
</body>
<script>
// 使用lodash對請求方法做防抖,    
let sendPost = _.debounce(function(data){
    //這里有問題,這里的返回值不能作為sendPost方法執行的返回值,因為debounce內部包裹了一層
    return axios({
        url: 'http://nodejs-cloud-studio-demo-bkzxs.nodejs-cloud-studio-demo.50185620.cn-hangzhou.fc.devsapp.net/test',
        method: 'post',
        data
    })
}, 300)
new Vue({
    el: '#app',
    mounted() {
        this.$refs.btn1.click()
        this.$refs.btn2.click()
    },
    methods: {
        onClick1: async function(){
            //這里有問題,sendPost返回值不是promise,而是undefined
            let res = await sendPost({username:'zs', age: 20})
            console.log('請求1的結果', res)
        },
        onClick2: async function(){
            let res = await sendPost({username:'zs', age: 20})
            console.log('請求2的結果', res)
        },
    },
})
</script>
</html>

方式2-通過取消ajax請求

(a) 概述

直接對請求方法做處理,通過ajax庫的api方法把重復的請求給取消掉

(b)原理

原生ajax取消請求

通過調用XMLHttpRequest對象實例的abort方法把請求給取消掉

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
</body>
<script>
//原生ajax的語法    
let xhr = new XMLHttpRequest();
xhr.open("GET", "http://nodejs-cloud-studio-demo-bkzxs.nodejs-cloud-studio-demo.50185620.cn-hangzhou.fc.devsapp.net/test?username=zs&age=20", true);
xhr.onload = function(){
    console.log(xhr.responseText)
}
xhr.send();
//在谷歌瀏覽器的低速3g下面測試
//通過XMLHttpRequest實例的abort方法取消請求
setTimeout(() => xhr.abort(), 100);
</script>
</html>

axios取消請求

通過axios的CancelToken對象實例cancel方法把請求給取消掉

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="https://lf9-cdn-tos.bytecdntp.com/cdn/expire-1-M/axios/0.26.0/axios.min.js" type="application/javascript"></script>
</head>
<body>
</body>
<script>
/*axios的取消的語法*/
// 方式1-通過axios.CancelToken.source產生cancelToken和cancel方法
/*
const source =  axios.CancelToken.source();
axios.get('http://nodejs-cloud-studio-demo-bkzxs.nodejs-cloud-studio-demo.50185620.cn-hangzhou.fc.devsapp.net/test', {
    params: {username: 'zs', age: 20}, 
    cancelToken: source.token
}).then(res=>{
    console.log('res', res.data)
}).catch(err=>{
    console.log('err', err)
})
//在谷歌瀏覽器的低速3g下面測試
//通過調用source的cancel方法取消
setTimeout(() => source.cancel(), 100);
*/

/**/
// 方式2-通過new axios.CancelToken產生cancelToken和cancel方法
let cancelFn 
const cancelToken =  new axios.CancelToken(cancel=>{
    cancelFn = cancel
});
axios.get('http://nodejs-cloud-studio-demo-bkzxs.nodejs-cloud-studio-demo.50185620.cn-hangzhou.fc.devsapp.net/test', {
    params: {username: 'zs', age: 20}, 
    cancelToken: cancelToken
}).then(res=>{
    console.log('res', res.data)
}).catch(err=>{
    console.log('err', err)
})
//在谷歌瀏覽器的低速3g下面測試
//通過調用cancelFn方法取消
setTimeout(() => cancelFn(), 100);

</script>
</html>

(c)代碼

步驟1-通過axios請求攔截器取消重復請求

通過axios請求攔截器,在每次請求前把請求信息和請求的取消方法放到一個map對象當中,并且判斷map對象當中是否已經存在該請求信息的請求,如果存在取消上傳請求

  • 流程圖

 

vue阻止重復請求(一般人不會,速度收藏)

 

代碼

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="https://lf26-cdn-tos.bytecdntp.com/cdn/expire-1-M/vue/2.6.14/vue.min.js" type="application/javascript"></script>
    <script src="https://lf9-cdn-tos.bytecdntp.com/cdn/expire-1-M/axios/0.26.0/axios.min.js" type="application/javascript"></script>
    <script src="https://lf3-cdn-tos.bytecdntp.com/cdn/expire-1-M/qs/6.10.3/qs.js" type="application/javascript"></script>

</head>
<body>
    <div id="app">
        <button @click="onClick1" ref="btn1">請求1</button>
        <button @click="onClick2" ref="btn2">請求2</button>
    </div>
</body>
<script>
//存儲請求信息和取消方法的的map對象    
const pendingRequest = new Map();  
//根據請求的信息(請求方式,url,請求get/post數據),產生map的key
function getRequestKey(config){
    const { method, url, params, data } = config;
    return [method, url, Qs.stringify(params), Qs.stringify(data)].join("&");
}   
//請求攔截器
axios.interceptors.request.use(
    function (config) {
    //根據請求的信息(請求方式,url,請求get/post數據),產生map的key
    let requestKey = getRequestKey(config)
    //判斷請求是否重復
    if(pendingRequest.has(requestKey)){
        //取消上次請求
        let cancel = pendingRequest.get(requestKey)
        cancel()
        //刪除請求信息
        pendingRequest.delete(requestKey) 
    }
    //把請求信息,添加請求到map當中
    // 生成取消方法
    config.cancelToken = config.cancelToken || new axios.CancelToken(cancel => {
        // 把取消方法添加到map
        if (!pendingRequest.has(requestKey)) {
            pendingRequest.set(requestKey, cancel)
        }
    })
    return config;
  },
  (error) => {
     return Promise.reject(error);
  }
);
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
    })
}
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)
        },
    },
})
</script>
</html>

步驟2-通過axios響應攔截器處理請求成功

通過axios的響應攔截器,在請求成功后在map對象當中,刪除該請求信息的數據

  • 流程圖

 

vue阻止重復請求(一般人不會,速度收藏)

 

l

vue阻止重復請求(一般人不會,速度收藏)

 

代碼

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="https://lf26-cdn-tos.bytecdntp.com/cdn/expire-1-M/vue/2.6.14/vue.min.js" type="application/javascript"></script>
    <script src="https://lf9-cdn-tos.bytecdntp.com/cdn/expire-1-M/axios/0.26.0/axios.min.js" type="application/javascript"></script>
    <script src="https://lf3-cdn-tos.bytecdntp.com/cdn/expire-1-M/qs/6.10.3/qs.js" type="application/javascript"></script>

</head>
<body>
    <div id="app">
        <button @click="onClick1" ref="btn1">請求1</button>
        <button @click="onClick2" ref="btn2">請求2</button>
    </div>
</body>
<script>
//存儲請求信息和取消方法的的map對象    
const pendingRequest = new Map();  
//根據請求的信息(請求方式,url,請求get/post數據),產生map的key
function getRequestKey(config){
    const { method, url, params, data } = config;
    return [method, url, Qs.stringify(params), Qs.stringify(data)].join("&");
}   
//請求攔截器
axios.interceptors.request.use(
    function (config) {
    //根據請求的信息(請求方式,url,請求get/post數據),產生map的key
    let requestKey = getRequestKey(config)
    //判斷請求是否重復
    if(pendingRequest.has(requestKey)){
        //取消上次請求
        let cancel = pendingRequest.get(requestKey)
        cancel()
        //刪除請求信息
        pendingRequest.delete(requestKey) 
    }
    //把請求信息,添加請求到map當中
    // 生成取消方法
    config.cancelToken = config.cancelToken || new axios.CancelToken(cancel => {
        // 把取消方法添加到map
        if (!pendingRequest.has(requestKey)) {
            pendingRequest.set(requestKey, cancel)
        }
    })
    return config;
  },
  (error) => {
     return Promise.reject(error);
  }
);

//響應攔截器
axios.interceptors.response.use(
  (response) => {
        //請求成功
        //刪除請求的信息
        let requestKey = getRequestKey(response.config)
        if(pendingRequest.has(requestKey)){
            pendingRequest.delete(requestKey)   
        }
        return response;
   },
   (error) => {
        return Promise.reject(error);
   }
);
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
    })
}
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)
        },
    },
})
</script>
</html>

步驟3-通過axios響應攔截器處理請求失敗

通過axios的響應攔截器,在請求失敗后在map對象當中,刪除該請求信息的數據

  • 流程圖

 

vue阻止重復請求(一般人不會,速度收藏)

 


vue阻止重復請求(一般人不會,速度收藏)

 

代碼

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="https://lf26-cdn-tos.bytecdntp.com/cdn/expire-1-M/vue/2.6.14/vue.min.js" type="application/javascript"></script>
    <script src="https://lf9-cdn-tos.bytecdntp.com/cdn/expire-1-M/axios/0.26.0/axios.min.js" type="application/javascript"></script>
    <script src="https://lf3-cdn-tos.bytecdntp.com/cdn/expire-1-M/qs/6.10.3/qs.js" type="application/javascript"></script>

</head>
<body>
    <div id="app">
        <button @click="onClick1" ref="btn1">請求1</button>
        <button @click="onClick2" ref="btn2">請求2</button>
    </div>
</body>
<script>
//存儲請求信息和取消方法的的map對象    
const pendingRequest = new Map();  
//根據請求的信息(請求方式,url,請求get/post數據),產生map的key
function getRequestKey(config){
    const { method, url, params, data } = config;
    return [method, url, Qs.stringify(params), Qs.stringify(data)].join("&");
}   
//請求攔截器
axios.interceptors.request.use(
    function (config) {
    //根據請求的信息(請求方式,url,請求get/post數據),產生map的key
    let requestKey = getRequestKey(config)
    //判斷請求是否重復
    if(pendingRequest.has(requestKey)){
        //取消上次請求
        let cancel = pendingRequest.get(requestKey)
        cancel()
        //刪除請求信息
        pendingRequest.delete(requestKey) 
    }
    //把請求信息,添加請求到map當中
    // 生成取消方法
    config.cancelToken = config.cancelToken || new axios.CancelToken(cancel => {
        // 把取消方法添加到map
        if (!pendingRequest.has(requestKey)) {
            pendingRequest.set(requestKey, cancel)
        }
    })
    return config;
  },
  (error) => {
     return Promise.reject(error);
  }
);
//刪除請求信息
function delPendingRequest(config){
    let requestKey = getRequestKey(config)
    if(pendingRequest.has(requestKey)){
        pendingRequest.delete(requestKey)   
    } 
}
//響應攔截器
axios.interceptors.response.use(
  (response) => {
        //請求成功
        //刪除請求的信息
        delPendingRequest(response.config)
        return response;
   },
   (error) => {
        //請求失敗
        //不是取消請求的錯誤
        if (!axios.isCancel(error)){
            //服務器報400,500報錯,刪除請求信息
            delPendingRequest(error.config || {})
        } 
        return Promise.reject(error);
   }
);
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
    })
}
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)
        },
    },
})
</script>
</html>

(d)存在的問題

通過取消ajax請求的方式,雖然避免重復請求,但是多個請求只有最后一次請求獲取數據成功,其他請求會產生報錯,沒辦法實現多個請求都獲取同一個請求結果,會影響接下來代碼正常執行

方式3-通過緩存ajax結果

(a)概述

直接對請求方法做處理,通過ajax庫的api方法在請求之前先訪問緩存列表,如果有結果那么從緩存當中獲取結果,如果沒有再向服務器索要數據

(b)代碼

步驟1-通過axios請求攔截器,設置config.adapter自定義處理請求

設置config.adapter后,請求會被攔截,不會再向服務器發請求

 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="https://lf9-cdn-tos.bytecdntp.com/cdn/expire-1-M/axios/0.26.0/axios.min.js" type="application/javascript"></script>
</head>
<body>
</body>
<script>
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) {
    // 通過,config.adapter,允許自定義處理請求
    config.adapter = function (config) {
        return new Promise((resolve) => {
          const res = {
            data: 'hello',
            status: 200,
            statusText: 'OK',
            headers: { 'content-type': 'text/plain; charset=utf-8' },
            config,
            request: {}
          }
          return resolve(res)
        })
    }
    return config
})
;(function(){
    sendPost({username:'zs', age: 20}).then(res=>{
        console.log('res1',res.data)
    })
    sendPost({username:'zs', age: 20}).then(res=>{
        console.log('res2',res.data)
    })
})();
</script>
</html>

步驟2-定義緩存對象,在請求和響應攔截器使用緩存

定義緩存對象,提供查詢和添加的方法,并且緩存需要設置大小和超時時間

  • 流程圖

 

vue阻止重復請求(一般人不會,速度收藏)

 

代碼

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="https://lf26-cdn-tos.bytecdntp.com/cdn/expire-1-M/vue/2.6.14/vue.min.js" type="application/javascript"></script>
    <script src="https://lf9-cdn-tos.bytecdntp.com/cdn/expire-1-M/axios/0.26.0/axios.min.js" type="application/javascript"></script>
    <script src="https://lf3-cdn-tos.bytecdntp.com/cdn/expire-1-M/qs/6.10.3/qs.js" type="application/javascript"></script>
</head>
<body>
    <div id="app">
        <button @click="onClick1" ref="btn1">請求1</button>
        <button @click="onClick2" ref="btn2">請求2</button>
    </div>
</body>
<script>
// 緩存對象
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)
        },
    },
})
</script>
</html>

分享到:
標簽:vue
用戶無頭像

網友整理

注冊時間:

網站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網站吧!
最新入駐小程序

數獨大挑戰2018-06-03

數獨一種數學游戲,玩家需要根據9

答題星2018-06-03

您可以通過答題星輕松地創建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學四六

運動步數有氧達人2018-06-03

記錄運動步數,積累氧氣值。還可偷

每日養生app2018-06-03

每日養生,天天健康

體育訓練成績評定2018-06-03

通用課目體育訓練成績評定