一文聊聊vue怎么阻止重复请求

vue怎么阻止重复请求?下面本篇文章给大家介绍一下vue阻止重复请求的两种方式,希望对大家有所帮助!

一文聊聊vue怎么阻止重复请求

项目当中前端代码会遇到同一个请求向服务器发了多次的情况,我们要避免服务器资源浪费,同一个请求一定时间只允许发一次请求

思路

(1)如果业务简单,例如同一个按钮防止多次点击,我们可以用定时器做防抖处理
(2)如果业务复杂,例如多个组件通过代码,同一个请求发多次,这个时候防抖已经不好处理了,最好是对重复的ajax请求统一做取消操作

实现

方式1-通过定时器做防抖处理

立即学习“前端免费学习笔记(深入)”;

(a)概述

效果:当用户连续点击多次同一个按钮,最后一次点击之后,过小段时间后才发起一次请求
原理:每次调用方法后都产生一个定时器,定时器结束以后再发请求,如果重复调用方法,就取消当前的定时器,创建新的定时器,等结束后再发请求,工作当中可以用第三方封装的工具函数例如lodash的debounce方法来简化防抖的代码  【相关推荐:vuejs视频教程、vuejs视频教程】

(b)代码

nbsp;html>                Document                
            
// 定义请求接口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), },})

登录后复制

(c)预览

vuejs视频教程

(d)存在的问题

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

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

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

nbsp;html>                Document                
                    
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), },})

登录后复制

vuejs视频教程

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

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

nbsp;html>                Document                
                    
// 使用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) }, },})

登录后复制

vuejs视频教程

方式2-通过取消ajax请求

(a) 概述

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

(b)原理

原生ajax取消请求

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

nbsp;html>                Document//原生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);

登录后复制

vuejs视频教程

axios取消请求

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

nbsp;html>                Document    /*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);

登录后复制

vuejs视频教程

(c)代码

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

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

nbsp;html>                Document                
                    
//存储请求信息和取消方法的的map对象 const pendingRequest = new Map(); //根据请求的信息(请求方式,url,请求get/post数据),产生map的keyfunction 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) }, },})

登录后复制

vuejs视频教程

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

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

nbsp;html>                Document                
                    
//存储请求信息和取消方法的的map对象 const pendingRequest = new Map(); //根据请求的信息(请求方式,url,请求get/post数据),产生map的keyfunction 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) }, },})

登录后复制

vuejs视频教程

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

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

nbsp;html>                Document                
                    
//存储请求信息和取消方法的的map对象 const pendingRequest = new Map(); //根据请求的信息(请求方式,url,请求get/post数据),产生map的keyfunction 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) }, },})

登录后复制

vuejs视频教程

(学习视频分享:vuejs视频教程、vuejs视频教程)

以上就是一文聊聊vue怎么阻止重复请求的详细内容,更多请关注【创想鸟】其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至253000106@qq.com举报,一经查实,本站将立刻删除。

发布者:PHP中文网,转转请注明出处:https://www.chuangxiangniao.com/p/3230758.html

(0)
上一篇 2025年4月1日 16:43:24
下一篇 2025年4月1日 16:43:33

AD推荐 黄金广告位招租... 更多推荐

相关推荐

发表回复

登录后才能评论