前言
在开发中,经常会遇到接口重复请求导致的各种问题。
对于重复的网络请求,会导致页面更新多次,发生页面抖动的现象,影响用户体验。
例如当前页面请求还未响应完成,就切换到其他路由,那么这些请求直到响应返回才会中止。
无论从用户体验或者从业务严谨方面来说,取消无用的请求确实是需要避免的。
实现思路
** 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}"htmlcode">// 请求响应回来执行这个函数 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来进行取消请求;当会有一些问题。
- 需要配置请求文件,不友好,团队开发配置也比较麻烦。
- 需要给每个请求都配置CancelToken。 有两个方法使用它 具体可以参考官网文档
免责声明:本站文章均来自网站采集或用户投稿,网站不提供任何软件下载或自行开发的软件! 如有用户或公司发现本站内容信息存在侵权行为,请邮件告知! 858582#qq.com
《魔兽世界》大逃杀!60人新游玩模式《强袭风暴》3月21日上线
暴雪近日发布了《魔兽世界》10.2.6 更新内容,新游玩模式《强袭风暴》即将于3月21 日在亚服上线,届时玩家将前往阿拉希高地展开一场 60 人大逃杀对战。
艾泽拉斯的冒险者已经征服了艾泽拉斯的大地及遥远的彼岸。他们在对抗世界上最致命的敌人时展现出过人的手腕,并且成功阻止终结宇宙等级的威胁。当他们在为即将于《魔兽世界》资料片《地心之战》中来袭的萨拉塔斯势力做战斗准备时,他们还需要在熟悉的阿拉希高地面对一个全新的敌人──那就是彼此。在《巨龙崛起》10.2.6 更新的《强袭风暴》中,玩家将会进入一个全新的海盗主题大逃杀式限时活动,其中包含极高的风险和史诗级的奖励。
《强袭风暴》不是普通的战场,作为一个独立于主游戏之外的活动,玩家可以用大逃杀的风格来体验《魔兽世界》,不分职业、不分装备(除了你在赛局中捡到的),光是技巧和战略的强弱之分就能决定出谁才是能坚持到最后的赢家。本次活动将会开放单人和双人模式,玩家在加入海盗主题的预赛大厅区域前,可以从强袭风暴角色画面新增好友。游玩游戏将可以累计名望轨迹,《巨龙崛起》和《魔兽世界:巫妖王之怒 经典版》的玩家都可以获得奖励。