JavaScript如何实现防止重复的网络请求的示例


Posted in Javascript onJanuary 28, 2021

前言

在开发中,经常会遇到接口重复请求导致的各种问题。
对于重复的网络请求,会导致页面更新多次,发生页面抖动的现象,影响用户体验。
例如当前页面请求还未响应完成,就切换到其他路由,那么这些请求直到响应返回才会中止。
无论从用户体验或者从业务严谨方面来说,取消无用的请求确实是需要避免的。

实现思路

JavaScript如何实现防止重复的网络请求的示例

**  1.在发送请求前先拦截当前请求地址 (url + 方法 + 参数);
**  2.开启一个请求队列用于保存 当前地址;
**  3.每次请求查看请求队列里面有没有当前url地址;
**  4.如果请求队列里有当前url地址就取消当前请求,
**  5.如果没有就发送请求,当请求数据返回后,请求队列里清除当前url地址。

1.平时我们写接口是这样的:

请求接口文件

import { http } from '@/plugin/axios'; // 导入请求接口 http

// 初始化
export function getInit(params) {
  return http({
    method: 'get',
    url: '/xxx/xxx/xx',
    params,
  });
}

主要就是这里执行 http方法的时候做操作;
执行http函数的时候能获取到请求所有配置 config ,返回promise对象。

2.这里演示使用axios,思路是执行请求函数的时候外面包一层

axios.js配置文件

import axios from 'axios';
import { httpRequest, completeRequest } from './options'; // 这里就是我们要实现的逻辑文件

// 里面做一些请求拦截,响应拦截操作 具体查看axios文档
const service = axios.create({
  baseURL: 'xxx/xxx',
});

// 请求拦截器
service.interceptors.request.use(config => {}, error => {})

// 响应拦截器
service.interceptors.response.use(response => {
 completeRequest(response); // 2.响应请求回来执行
}, error => {
 
})

export function http(config) { // => 这里config就是传递的请求配置参数
  return httpRequest(config, service); // + 1.在这里做一些逻辑操作
}

3.防止重复网络配置文件

options.js
(1)发送请求前,查看请求队列里是否有当前请求(url地址来判断)

  • 请求队列有当前url地址, 取消请求  返回promise.reject失败
  • 没有当前请求,正常发送请求;
/**
 * 职责: 防止重复的网络请求
 *
 */

let list = new Set(); // 1.请求队列

// 合并 方法 参数 url地址
function getUrl(config = {}) {
 // get请求 params参数 post请求 data参数, baseURL
 const { url, method, params, data, baseURL = '' } = config;
 const urlVal = url.replace(baseURL, '');
 return `${urlVal}?${method === 'get' ? getformatObjVal(params) : getformatObjVal(data)}`;
}

// 处理 url地址 
const getformatObjVal = (obj) => {
 obj = typeof obj === 'string' ? JSON.parse(`${obj}`) : obj;
 var str = [];
 for (let p in obj) {
  if (obj.hasOwnProperty(p) && p !== '_t') {
   var item = obj[p] === null ? '' : obj[p]; // 处理null
   str.push(encodeURIComponent(p) + '=' + encodeURIComponent(item));
  }
 }
 return str.join('&');
}

// 2.请求方法
export function httpRequest(config = {}, axios) {
 const url = getUrl(config); //3. 这里我们获取到了URL地址

 if (list.has(url)) { // 4.查看请求队列是否有当前url地址
  return Promise.reject('In the request'); // 5.在请求队列里面 取消当前请求, 返回Promise失败结果
 }
 
 // 6. 请求队列没有当前url地址 发送请求并把url地址存入请求队列里
 list.add(url);
 return Promise.resolve(axios); 
}

(2)请求响应回来后,在请求队列里删除当前url地址; (下一次请求就可以正常发送)
​ options.js

// 请求响应回来执行这个函数
export function completeRequest(response = {}) {
 const { config } = response; // 1.response里面config能拿到配置参数
 const url = getUrl(config); // 2.获取url地址 
 if (list.has(url)) {
  list.delete(url); // 3.删除请求队列中的当前请求url地址
 }
}

axios.js

import axios from 'axios';
import { httpRequest, completeRequest } from './options'; // 防止重复请求

const service = axios.create({
  baseURL: 'xxx/xxx',
});

// 请求拦截器
service.interceptors.request.use(config => {}, error => {})

// 响应拦截器
service.interceptors.response.use(response => {
 completeRequest(response); // 2.响应请求回来执行 +
}, error => {
 
})


// 导出请求
export function http(config) {
  return httpRequest(config, service); // 1.发送请求前执行
}

到这里已经实现了防止重复的网络请求,但还有一个问题,响应请求发生异常了要清除请求队列中当前url地址。不清理,下一次发送请求直接被取消掉 (这里我就随便写了一个方法,把请求队列全部清空,大家可以按自己场景来写)。

/**
 * 清空所有请求队列
 */
export function clearRequestList() {
 list = new Set(); // 这里我就直接清空了
}

完整http.js文件

import axios from 'axios';
import { httpRequest, completeRequest, clearRequestList } from './options'; // 防止重复请求 +

const service = axios.create({
  baseURL: 'xxx/xxx',
});

// 请求拦截器
service.interceptors.request.use(config => {}, error => {})

// 响应拦截器
service.interceptors.response.use(response => {
 completeRequest(response); // 2.响应请求回来执行
}, error => {
 clearRequestList(); // + 
})


// 导出请求
export function http(config) {
  return httpRequest(config, service); // 1.发送请求前执行
}

完整options.js

/**
 * 职责: 防止重复的网络请求
 *
 */

let list = new Set(); // 1.请求队列

// 合并 方法 参数 url地址
function getUrl(config = {}) {
 // get请求 params参数 post请求 data参数, baseURL
 const { url, method, params, baseURL = '' } = config;
 const urlVal = url.replace(baseURL, '');
 return `${urlVal}?${method === 'get' ? getformatObjVal(params) : 'post'}`;
}

// 处理 url地址 
const getformatObjVal = (obj) => {
 obj = typeof obj === 'string' ? JSON.parse(`${obj}`) : obj;
 var str = [];
 for (let p in obj) {
  if (obj.hasOwnProperty(p) && p !== '_t') {
   var item = obj[p] === null ? '' : obj[p]; // 处理null
   str.push(encodeURIComponent(p) + '=' + encodeURIComponent(item));
  }
 }
 return str.join('&');
}

// 2.请求方法
export function httpRequest(config = {}, axios) {
 const url = getUrl(config); //3. 这里我们获取到了URL地址

 if (list.has(url)) { // 4.查看请求队列是否有当前url地址
  return Promise.reject('In the request'); // 5.在请求队列里面 取消当前请求, 返回Promise失败结果
 }

 // 6. 请求队列没有当前url地址 发送请求并把url地址存入请求队列里
 list.add(url);
 return Promise.resolve(axios);
}


/**
 * 请求响应回来执行这个函数
 */
export function completeRequest(response = {}) {
 const { config } = response; // 1.response里面config能拿到配置参数
 const url = getUrl(config); // 2.获取url地址 
 list.has(url) && list.delete(url); // 3.删除请求队列中的当前请求url地址
}

/**
 * 清空所有请求队列
 */
export function clearRequestList(error) {
 // error 可以获取到配置, 做一些操作。
 list = new Set(); // 这里我就直接清空了
}

以上就是我实现防止网络请求的方式,之前我有使用过axios中CancelToken来进行取消请求;当会有一些问题。

  1. 需要配置请求文件,不友好,团队开发配置也比较麻烦。
  2. 需要给每个请求都配置CancelToken。  有两个方法使用它 具体可以参考官网文档

到此这篇关于JavaScript如何实现防止重复的网络请求的示例的文章就介绍到这了,更多相关JavaScript 防止重复的网络请求内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Javascript 相关文章推荐
jQuery对象和DOM对象的相互转化实现代码
Mar 02 Javascript
jQuery UI Datepicker length为空或不是对象错误的解决方法
Dec 19 Javascript
为JavaScript类型增加方法的实现代码(增加功能)
Dec 29 Javascript
QQ空间顶部折页撕开效果示例代码
Jun 15 Javascript
基于js与flash实现的网站flv视频播放插件代码
Oct 14 Javascript
JavaScript实现SHA-1加密算法的方法
Mar 11 Javascript
微信支付如何实现内置浏览器的H5页面支付
Sep 25 Javascript
使用vue.js开发时一些注意事项
Apr 27 Javascript
详解Vue源码学习之双向绑定
Apr 10 Javascript
Vue+iview+webpack ie浏览器兼容简单处理
Sep 20 Javascript
一篇文章带你浅入webpack的DLL优化打包
Feb 20 Javascript
JavaScript实现沿五角星形线摆动的小圆实例详解
Jul 28 Javascript
JavaScript实现跟随鼠标移动的盒子
Jan 28 #Javascript
vue.js实现点击图标放大离开时缩小的代码
Jan 27 #Vue.js
使用JS实现鼠标放上图片进行放大离开实现缩小功能
Jan 27 #Javascript
vscode自定义vue模板的实现
Jan 27 #Vue.js
vue+echarts实现中国地图流动效果(步骤详解)
Jan 27 #Vue.js
js实现鼠标切换图片(无定时器)
Jan 27 #Javascript
JavaScript实现切换多张图片
Jan 27 #Javascript
You might like
PHP根据IP地址获取所在城市具体实现
2013/11/27 PHP
PHP fastcgi模式上传大文件(大约有300多K)报错
2014/09/28 PHP
php中strtotime函数用法详解
2014/11/15 PHP
javascript 打开页面window.location和window.open的区别
2010/03/17 Javascript
js 利用className得到对象的实现代码
2011/11/15 Javascript
页面调用单个swf文件,嵌套出多个方法。
2011/11/21 Javascript
javascript倒计时功能实现代码
2012/06/07 Javascript
javascript 图片裁剪技巧解读
2012/11/15 Javascript
jQuery中slideUp()方法用法分析
2014/12/24 Javascript
js运动动画的八个知识点
2015/03/12 Javascript
JavaScript 浏览器兼容性总结及常用浏览器兼容性分析
2016/03/30 Javascript
JavaScript lodash常见用法系列小结
2016/08/24 Javascript
Javascript之面向对象--接口
2016/12/02 Javascript
bootstrap table配置参数例子
2017/01/05 Javascript
Webpack实现按需打包Lodash的几种方法详解
2017/05/08 Javascript
jquery写出PC端轮播图实例
2018/01/26 jQuery
vue计算属性computed的使用方法示例
2019/03/13 Javascript
基于vue+axios+lrz.js微信端图片压缩上传方法
2019/06/25 Javascript
利用JS响应式修改vue实现页面的input值
2019/09/02 Javascript
[52:31]VP vs Serenity 2018国际邀请赛小组赛BO2 第二场 8.16
2018/08/17 DOTA
[54:05]DOTA2-DPC中国联赛定级赛 SAG vs iG BO3第一场 1月9日
2021/03/11 DOTA
python读文件逐行处理的示例代码分享
2013/12/27 Python
跟老齐学Python之大话题小函数(2)
2014/10/10 Python
django写用户登录判定并跳转制定页面的实例
2019/08/21 Python
Python3+Selenium+Chrome实现自动填写WPS表单
2020/02/12 Python
Python Selenium模块安装使用教程详解
2020/07/09 Python
Steve Madden官网:美国鞋类品牌
2017/01/29 全球购物
eHarmony英国:全球领先的认真恋爱约会平台之一
2020/11/16 全球购物
有针对性的求职自荐信
2013/11/14 职场文书
施工员岗位职责
2014/03/16 职场文书
我为党旗添光彩演讲稿
2014/09/13 职场文书
钳工实训报告总结
2014/11/04 职场文书
幼儿园大班教育随笔
2015/08/14 职场文书
浅谈Redis的keys命令到底有多慢
2021/10/05 Redis
世界十大动漫制作公司排行榜,迪士尼上榜,第二是美国代表性文化符
2022/03/18 欧美动漫
苹果可能正在打击不进行更新的 App
2022/04/24 数码科技