100字范文,内容丰富有趣,生活中的好帮手!
100字范文 > < 今日小技巧:Axios封装 接口请求增加防抖功能 >

< 今日小技巧:Axios封装 接口请求增加防抖功能 >

时间:2020-04-21 17:56:33

相关推荐

< 今日小技巧:Axios封装 接口请求增加防抖功能 >

文章目录

👉 前言👉 一、核心代码 : 防抖函数👉 二、Axios封装中的配置👉 三、实现原理👉 结论👉 补充优化: 解决多个接口请求,拦截掉了需要的请求> 防抖函数> 引用位置 往期内容 💨

👉 前言

防抖节流概念: < 性能优化:认识防抖与节流,如何实现呢?它们又有何区别? >

今天这篇文章,主要是讲述对axios封装的请求,由于部分请求可能存在延时的情况。使得接口可能存在会被持续点击(即:接口未响应的时间内,被持续请求),导致重复请求的问题,容易降低前后端服务的性能!

故提出给axios封装的配置里面,新增一个防抖函数,用来限制全局请求的防抖。不过介于部分接口可能存在需要持续请求的情况,所以增加一个参数来判断是否启用防抖函数

👉 一、核心代码 : 防抖函数

const debounce = (fn, delay, immediate = true) => {// 1.定义一个定时器, 保存上一次的定时器let timeout = JSON.parse(localStorage.getItem('timeout')) || null// window.console.log(fn, delay, timeout)// 2.真正执行的函数const _debounce = function() {let context = this;let args = arguments;if (timeout) clearTimeout(timeout); // timeout 不为nullif (immediate) {// 第一次会立即执行,以后只有事件执行后才会再次触发let callNow = !timeout;timeout = setTimeout(function() {timeout = null;}, delay)if (callNow) {fn.apply(context, args)}} else {timeout = setTimeout(function() {fn.apply(context, args)}, delay);}localStorage.setItem('timeout', timeout)}// 封装取消功能_debounce.cancel = function() {if (timeout) clearTimeout(timeout)timeout = nulllocalStorage.setItem('timeout', null)}return _debounce}export default debounce;

👉 二、Axios封装中的配置

// 使用axios请求this.xxxName({...isDebounce: true // 入参}).then((res) => {...}).finally(() => {});---------------------------------------------------import debounce from "./debounce.js";export default function(options) {// options 为接口入参配置,options.data为接口参数...let isDebounce = false;try{isDebounce = config.data.isDebounce;if(isDebounce) {delete data.isDebounce;}} catch(e){//TODO handle the exceptionisDebounce = false}return createPromise(type, url, data, config, socket, cache, isDebounce);}function createPromise(type, url, data, config, socket, cache = {}, isDebounce = false) {...return new Promise(function(resolve, reject) {if (cacheData) {resolve(cacheData);} else {const fn = () => {// 请求接口代码http.then(function(res) {...}).catch(function(res) {...reject(res);}).finally(() => {debounce().cancel()});}// 对axios请求进行防抖配置, 防抖时间为 5sif(isDebounce) {debounce(fn, 5000)()} else {fn()}}});}

👉 三、实现原理

介于我们封装axios后,每次请求都会统一执行一次我们封装的函数。从而统一在函数内进行防抖判断,防止短时间发出大量误触请求!

因为小温是在项目后期进行功能优化,所以以入参的形式(默认关闭)控制是否开启防抖功能!

难点:由于防抖函数位于axios封装方法中,所以每次请求都无法获取到上次执行遗留下来的timer。相当于每次执行的防抖函数都为新的函数,导致timer变量无法被闭包存储,无法起到请求防抖的功能! 故而通过将timer暂存至本地,解决问题!

给防抖函数增加中断防抖的功能,在请求响应后通过cancel函数关闭当前防抖流程!

👉 结论

本篇文章仅是基于实际开发中,对防抖概念的实际应用。可能部分逻辑存在问题,需要各位小伙伴在使用时,根据实际场景做修改! 本文仅用于思路指导!在实际运用还是存在问题: 比如当存在两个及以上接口同时请求时,会使防抖函数失效,导致后请求的接口被强行取消。

这个问题也需要重点去解决! 但是本项目中,仅用于列表接口查询时的防抖,故暂不解决这个问题!

原因: 出现问题的原因也很简单, 由于timer只存一个参数,防抖函数无法准确的判断防抖对象, 就是同时请求的接口,后面的接口被当作第一个触发的请求接口的抖动请求(也就是防抖防错对象了),故被防抖阻止了。

解决思路: 将本地存储的数据,存储为object类型, 按接口地址Url作为 key值存储timer,请求之前,查询当前Url,在本地存储中查询有没有正在执行的请求!若有,则进入防抖。反之,则执行正常请求流程!

👉 补充优化: 解决多个接口请求,拦截掉了需要的请求

> 防抖函数

const debounce = (fn, delay, url = '', immediate = true) => {// 1.定义一个定时器, 保存上一次的定时器let timeout = JSON.parse(localStorage.getItem(url)) || null// window.console.log(url, timeout)// 2.真正执行的函数const _debounce = function() {let context = this;let args = arguments;if (timeout) clearTimeout(timeout); // timeout 不为null... 中间内容不变localStorage.setItem(url, timeout)}// 封装取消功能_debounce.cancel = function() {let timeout_cancel = JSON.parse(localStorage.getItem(url)) || nullif (timeout_cancel) clearTimeout(timeout_cancel)timeout = nulllocalStorage.removeItem(url)}return _debounce}export default debounce;

> 引用位置

新增入参 Url ,请求地址,如果怕接口信息被网站获取,导致泄漏! 可以以斜杠为分割字符串,使用sqit('/')分割! 取最后一个作为本地存储的标记(key)值

最后的最后,如果觉得小温这篇文章对你有所帮助,请不要吝惜你的小手,给小温三连支持一下吧~ 😘

往期内容 💨

🔥 < 每日算法 - JavaScript解析:跳跃游戏 Ⅰ/ Ⅱ - 贪心 >

🔥 < 每日算法 - JavaScript解析:一文解决 “ 买卖股票 ” 系列算法题 >

🔥 < vue + ElementUi 组件封装:实现弹窗展示富文本数据,允许全文搜索高亮显示搜索内容 >

🔥 < 每日算法:一文带你认识 “ 双指针算法 ” >

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。