Maison > interface Web > Voir.js > Parlons de la façon dont Vue empêche les requêtes répétées dans cet article

Parlons de la façon dont Vue empêche les requêtes répétées dans cet article

青灯夜游
Libérer: 2023-01-29 09:22:18
avant
2928 Les gens l'ont consulté

Comment vue empêche-t-il les requêtes répétées ? L'article suivant présentera deux façons permettant à Vue d'éviter les requêtes répétées. J'espère qu'il vous sera utile !

Parlons de la façon dont Vue empêche les requêtes répétées dans cet article

Le code front-end du projet rencontrera la situation où la même demande est envoyée plusieurs fois au serveur. Nous devons éviter de gaspiller les ressources du serveur. La même demande ne peut être envoyée qu'une seule fois dans une certaine période. de temps

Pensées

(1) Si l'entreprise est simple, comme empêcher plusieurs clics sur le même bouton, nous pouvons utiliser une minuterie pour le traitement anti-tremblement
(2) Si l'entreprise est complexe, comme plusieurs composants passant par le code et la même requête étant envoyée plusieurs fois, le processus anti-shake est déjà terminé C'est difficile à gérer, il est préférable d'annuler les requêtes ajax répétées de manière unifiée

pour y parvenir

Méthode 1 - Traitement anti-tremblement via minuterie

(a) Présentation

Effet  : Lorsque l'utilisateur clique plusieurs fois de suite sur le même bouton, une demande sera lancée après une courte période de temps après le dernier clic
Principe : Un minuteur est généré après l'appel de chaque méthode, et la demande sera envoyée après l'expiration du minuteur. Si l'appel répété de la méthode annulera le minuteur actuel, créera un nouveau minuteur, puis enverra la demande. après la fin. Vous pouvez utiliser des fonctions d'outils encapsulés tiers telles que la méthode debounce code> de <code>lodash pour simplifier le code anti-tremblement [Recommandations associées : Tutoriel vidéo vuejslodashdebounce方法来简化防抖的代码  【相关推荐:vuejs视频教程web前端开发

(b)代码

<!DOCTYPE html>
<html>
<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: &#39;https://nodejs-cloud-studio-demo-bkzxs.nodejs-cloud-studio-demo.50185620.cn-hangzhou.fc.devsapp.net/test&#39;,
        method: &#39;post&#39;,
        data
    })
}
new Vue({
    el: &#39;#app&#39;,
    methods: {
        // 调用lodash的防抖方法debounce,实现连续点击按钮多次,0.3秒后调用1次接口
        onClick: _.debounce(async function(){
            let res = await sendPost({username:&#39;zs&#39;, age: 20})
            console.log(&#39;请求的结果&#39;, res.data)
        }, 300),
    },
})
</script>
</html>
Copier après la connexion

(c)预览

连接

(d)存在的问题

无法解决多个按钮件的重复请求的发送问题,例如下面两种情况

情况-在点击事件上做防抖

按钮事件间是相互独立的,调用的是不同方法,做不到按钮间防抖效果

<!DOCTYPE html>
<html>
<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: &#39;http://nodejs-cloud-studio-demo-bkzxs.nodejs-cloud-studio-demo.50185620.cn-hangzhou.fc.devsapp.net/test&#39;,
        method: &#39;post&#39;,
        data
    })
}
new Vue({
    el: &#39;#app&#39;,
    mounted() {
        this.$refs.btn1.click()
        this.$refs.btn2.click()
    },
    methods: {
        // 使用lodash对请求方法做防抖
        //这里有问题,只是对每个按钮的点击事件单独做了防抖,但是两个按钮之间做不到防抖的效果
        onClick1: _.debounce(async function(){
            let res = await sendPost({username:&#39;zs&#39;, age: 20})
            console.log(&#39;请求1的结果&#39;, res.data)
        }, 300),
        onClick2: _.debounce(async function(){
            let res = await sendPost({username:&#39;zs&#39;, age: 20})
            console.log(&#39;请求2的结果&#39;, res.data)
        }, 300),
    },
})
</script>
</html>
Copier après la connexion

预览

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

按钮间调用的方法是相同的,是可以对方法做防抖处理,但是处理本身对方法做了一次封装,会影响到之前方法的返回值接收,需要对之前的方法做更多处理,变得更加复杂,不推荐

<!DOCTYPE html>
<html>
<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: &#39;http://nodejs-cloud-studio-demo-bkzxs.nodejs-cloud-studio-demo.50185620.cn-hangzhou.fc.devsapp.net/test&#39;,
        method: &#39;post&#39;,
        data
    })
}, 300)
new Vue({
    el: &#39;#app&#39;,
    mounted() {
        this.$refs.btn1.click()
        this.$refs.btn2.click()
    },
    methods: {
        onClick1: async function(){
            //这里有问题,sendPost返回值不是promise,而是undefined
            let res = await sendPost({username:&#39;zs&#39;, age: 20})
            console.log(&#39;请求1的结果&#39;, res)
        },
        onClick2: async function(){
            let res = await sendPost({username:&#39;zs&#39;, age: 20})
            console.log(&#39;请求2的结果&#39;, res)
        },
    },
})
</script>
</html>
Copier après la connexion

预览

方式2-通过取消ajax请求

(a) 概述

直接对请求方法做处理,通过ajax库的api方法把重复的请求给取消掉

(b)原理

原生ajax取消请求

通过调用XMLHttpRequest对象实例的abort方法把请求给取消掉

<!DOCTYPE html>
<html>
<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>
Copier après la connexion

预览

axios取消请求

通过axiosCancelToken对象实例cancel方法把请求给取消掉

<!DOCTYPE html>
<html>
<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(&#39;http://nodejs-cloud-studio-demo-bkzxs.nodejs-cloud-studio-demo.50185620.cn-hangzhou.fc.devsapp.net/test&#39;, {
    params: {username: &#39;zs&#39;, age: 20}, 
    cancelToken: source.token
}).then(res=>{
    console.log(&#39;res&#39;, res.data)
}).catch(err=>{
    console.log(&#39;err&#39;, 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(&#39;http://nodejs-cloud-studio-demo-bkzxs.nodejs-cloud-studio-demo.50185620.cn-hangzhou.fc.devsapp.net/test&#39;, {
    params: {username: &#39;zs&#39;, age: 20}, 
    cancelToken: cancelToken
}).then(res=>{
    console.log(&#39;res&#39;, res.data)
}).catch(err=>{
    console.log(&#39;err&#39;, err)
})
//在谷歌浏览器的低速3g下面测试
//通过调用cancelFn方法取消
setTimeout(() => cancelFn(), 100);

</script>
</html>
Copier après la connexion

预览

(c)代码

步骤1-通过axios请求拦截器取消重复请求

通过axios请求拦截器,在每次请求前把请求信息和请求的取消方法放到一个map对象当中,并且判断map对象当中是否已经存在该请求信息的请求,如果存在取消上传请求

<!DOCTYPE html>
<html>
<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: &#39;http://nodejs-cloud-studio-demo-bkzxs.nodejs-cloud-studio-demo.50185620.cn-hangzhou.fc.devsapp.net/test&#39;,
        method: &#39;post&#39;,
        data
    })
}
new Vue({
    el: &#39;#app&#39;,
    mounted() {
        this.$refs.btn1.click()
        this.$refs.btn2.click()
    },
    methods: {
        // 使用lodash对请求方法做防抖
        //这里有问题,只是对每个按钮的点击事件单独做了防抖,但是两个按钮之间做不到防抖的效果
        onClick1: async function(){
            let res = await sendPost({username:&#39;zs&#39;, age: 20})
            console.log(&#39;请求1的结果&#39;, res.data)
        },
        onClick2: async function(){
            let res = await sendPost({username:&#39;zs&#39;, age: 20})
            console.log(&#39;请求2的结果&#39;, res.data)
        },
    },
})
</script>
</html>
Copier après la connexion

预览

步骤2-通过axios响应拦截器处理请求成功

通过axios, développement web front-end

(b) code

<!DOCTYPE html>
<html>
<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: &#39;http://nodejs-cloud-studio-demo-bkzxs.nodejs-cloud-studio-demo.50185620.cn-hangzhou.fc.devsapp.net/test&#39;,
        method: &#39;post&#39;,
        data
    })
}
new Vue({
    el: &#39;#app&#39;,
    mounted() {
        this.$refs.btn1.click()
        this.$refs.btn2.click()
    },
    methods: {
        // 使用lodash对请求方法做防抖
        //这里有问题,只是对每个按钮的点击事件单独做了防抖,但是两个按钮之间做不到防抖的效果
        onClick1: async function(){
            let res = await sendPost({username:&#39;zs&#39;, age: 20})
            console.log(&#39;请求1的结果&#39;, res.data)
        },
        onClick2: async function(){
            let res = await sendPost({username:&#39;zs&#39;, age: 20})
            console.log(&#39;请求2的结果&#39;, res.data)
        },
    },
})
</script>
</html>
Copier après la connexion

Connexion🎜🎜

(d) existe Le problème 🎜🎜 ne peut pas résoudre le problème de l'envoi de demandes répétées pour plusieurs parties de boutons , comme les deux situations suivantes 🎜

Situation - Anti-shake sur événement clic

🎜Bouton Les événements sont indépendants les uns des autres et appellent des méthodes différentes, donc l'anti- l'effet de tremblement entre les boutons ne peut pas être obtenu🎜
<!DOCTYPE html>
<html>
<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: &#39;http://nodejs-cloud-studio-demo-bkzxs.nodejs-cloud-studio-demo.50185620.cn-hangzhou.fc.devsapp.net/test&#39;,
        method: &#39;post&#39;,
        data
    })
}
new Vue({
    el: &#39;#app&#39;,
    mounted() {
        this.$refs.btn1.click()
        this.$refs.btn2.click()
    },
    methods: {
        // 使用lodash对请求方法做防抖
        //这里有问题,只是对每个按钮的点击事件单独做了防抖,但是两个按钮之间做不到防抖的效果
        onClick1: async function(){
            let res = await sendPost({username:&#39;zs&#39;, age: 20})
            console.log(&#39;请求1的结果&#39;, res.data)
        },
        onClick2: async function(){
            let res = await sendPost({username:&#39;zs&#39;, age: 20})
            console.log(&#39;请求2的结果&#39;, res.data)
        },
    },
})
</script>
</html>
Copier après la connexion
Copier après la connexion
🎜Aperçu 🎜🎜

Cas 2 - Faites-le dans l'interface méthode Anti-shake

🎜Les méthodes appelées entre les boutons sont les mêmes. Il est possible d'effectuer un traitement anti-shake sur la méthode, mais le traitement lui-même encapsule la méthode, ce qui affectera la réception de la valeur de retour de la méthode précédente. Il est nécessaire d'effectuer un traitement anti-shake sur la méthode précédente. Faites plus de traitement, devenez plus complexe, 🎜non recommandé🎜🎜rrreee🎜
Aperçu🎜🎜🎜🎜🎜Méthode 2 - En annulant la requête ajax🎜🎜🎜

( a) Présentation🎜🎜 Traitez directement la méthode de requête et annulez les requêtes en double via la méthode API de la bibliothèque ajax🎜

(b) Principe🎜

Demande d'annulation ajax native

🎜Annulez la demande en appelant la méthode abort de l'instance d'objet XMLHttpRequest🎜rrreee🎜
Aperçu 🎜 🎜< h4 data-id="heading-14">demande d'annulation d'axios🎜Grâce à l'instance d'objet CancelToken méthode cancel de axios Annuler la demande🎜rrreee🎜Aperçu 🎜🎜

(c) code 🎜

Étape 1 - Requête via axios L'intercepteur annule requêtes répétées

🎜Demandez l'intercepteur via axios, placez les informations de la demande et la méthode d'annulation demandée dans un objet cartographique avant chaque requête et déterminez si l'objet cartographique a été Il y a une demande de cette information de demande S'il y a une demande d'annulation du téléchargement🎜rrreee🎜
Aperçu 🎜🎜

Étape 2 - Traitement de la demande via l'intercepteur de réponse axios avec succès

🎜 Grâce à l'intercepteur de réponse de axios, une fois la requête réussie, supprimez les données des informations de la requête dans l'objet cartographique🎜rrreee🎜🎜Aperçu🎜🎜

步骤3-通过axios响应拦截器处理请求失败

通过axios的响应拦截器,在请求失败后在map对象当中,删除该请求信息的数据

<!DOCTYPE html>
<html>
<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: &#39;http://nodejs-cloud-studio-demo-bkzxs.nodejs-cloud-studio-demo.50185620.cn-hangzhou.fc.devsapp.net/test&#39;,
        method: &#39;post&#39;,
        data
    })
}
new Vue({
    el: &#39;#app&#39;,
    mounted() {
        this.$refs.btn1.click()
        this.$refs.btn2.click()
    },
    methods: {
        // 使用lodash对请求方法做防抖
        //这里有问题,只是对每个按钮的点击事件单独做了防抖,但是两个按钮之间做不到防抖的效果
        onClick1: async function(){
            let res = await sendPost({username:&#39;zs&#39;, age: 20})
            console.log(&#39;请求1的结果&#39;, res.data)
        },
        onClick2: async function(){
            let res = await sendPost({username:&#39;zs&#39;, age: 20})
            console.log(&#39;请求2的结果&#39;, res.data)
        },
    },
})
</script>
</html>
Copier après la connexion
Copier après la connexion

预览

(学习视频分享:vuejs入门教程编程基础视频

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Étiquettes associées:
source:juejin.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal