首先描述一下我所使用的业务场景:系统有一个批量审批的功能,每个审批的流程需要根据提交的用户实时的反馈回去进去用户页面的刷新,如果一个用户同时有多个流程被审批通过,前端会向服务端频繁的多次调用同一个接口,造成服务器压力过大和页面卡顿,非常影响用户体验。
目标:需要短时间内向服务端频繁调用接口时只去调用最后一次的接口。(防抖)
防抖和节流的区别:主要体现在执行次数上的区别,比如我们写一个200ms的延迟时间,节流就是每200ms执行一次,而抖动是只有在最后一次事件的200ms内调用一次回调函数。
防抖和节流都可以用于 mousemove、scroll、resize、input、click等事件,他们的区别在于防抖只会在连续的事件周期结束时执行一次,而节流会在事件周期内按间隔时间有规律的执行多次。
防抖 debounce
当事件被频繁触发时,在一定的时间内再去执行回调函数,如果在等待期间再次被触发,则重新计时,直至整个等待期间没有新的事件被触发,执行回调函数。
举个例子:一个点击事件,为了防止用户重复发起请求,如果用户在三秒内多次发生点击事件,点击事件将只执行一次,第一次和第二次点击的间隔只要在三秒钟内就会重置这个等待时间,第二次和第三次之间的最大等待时间也是三秒,如果第二次点击事件发生后的三秒内没有新的点击事件产生,第二次点击后的三秒就会调用回调函数。
可以直接引用loadsh的debounce方法来实现函数防抖,也可以自己写一个防抖函数(利用定时器)
-
引用loadsh
这里先给一个中文文档的地址:https://www.lodashjs.com/docs/lodash.debounce
在vue3.x中也推荐了这种方式:https://v3.vuejs.org/guide/data-methods.html#methods
有多种引用方式,这里我直接采用npm的方式
npm i --save lodash
使用loadsh的debounce方法
<el-button id="myBtn" type="goon" icon="el-icon-search" @click="test">点击事件</el-button>
let _ = require('lodash'); _.debounce(fun,ms,options) fun: 回调函数
ms:等待时间,毫秒
options:选项对象
注意:这里点击事件要写成test:
的形式,test()
这样是不生效的
import debounce from 'lodash/debounce' methods:{ test:debounce(()=>{ console.log("防抖函数执行",) },3000) } document.getElementById("myBtn").addEventListener('click', debounce(function (event) { console.log("防抖函数执行",) }, 3000))
-
1
-
2
-
3
-
4
-
5
-
6
-
7
-
8
-
9
-
10
-
11
-
12
-
13
-
14
-
自定义防抖函数
<el-button type="goon" icon="el-icon-search" @click="test">点击事件</el-button>
data:{ timer:null }, methods:{ test(){ clearTimeout(this.timer) this.timer = setTimeout(()=>{ console.log("防抖执行,这里就是你需要执行的操作") },3000) } }
-
1
-
2
-
3
-
4
-
5
-
6
-
7
-
8
-
9
-
10
-
11
-
12
-
13
-
14
-
15
节流 throttle
在规定的时间内只触发一次回调函数,在规定时间内多次触发函数,只会执行一次
举个例子:一个点击事件,你设定了节流的延迟时间为一秒钟,那么在你一直点击的情况下,每隔一秒会触发一次这个事件,直到你的点击停止,这个不会累积,比如一秒钟内点击了五次,然后不再点击时,事件也只会触发一次而不会累积到触发五次,这种累积的可以采用定时器实现。
节流一般多用于监听输入框和滚动条,同样的在我们的loadsh中也有写好的节流的函数throttle,使用方法和上面防抖类似,这里就不详细写了,主要写一下 自定义的节流函数。
throttle(fun, ms,options) fun:需要节流的回调函数
ms:等待时间
options:额外配置项
自定义节流函数:
原理就是用时间戳判断是否到了回调的执行时间,记录上次执行的时间戳,然后每次触发 事件执行回调,回调里边判断当前时间戳距离上一次执行时间戳的间隔是否已经到达规定的时间,如果是就执行,并且会更新上次执行的时间戳。
下面是我写的一个简单的例子,可以根据自己需求进行修改
data:{ lastTime:new Date() }, methods:{ throttle(fun){ let now = new Date() console.log("now",now) console.log("lastTime",this.lastTime) if (now - this.lastTime > 1000){ fun() this.lastTime = now } }, test(){ this.throttle(function (){ console.log("节流函数调用,时间1000ms") }) }, }
-
1
-
2
-
3
-
4
-
5
-
6
-
7
-
8
-
9
-
10
-
11
-
12
-
13
-
14
-
15
-
16
-
17
-
18
-
19
-
20
-
21
-
22
-
23
-
24
-
25
-
26
-
27
如果项目多次用到可以将以上的方法封装成一个工具类。
参考文章:https://www.jb51.net/article/161713.htm
蓝蓝设计建立了UI设计分享群,每天会分享国内外的一些优秀设计,如果有兴趣的话,可以进入一起成长学习,请扫码蓝小助,报下信息,蓝小助会请您入群。欢迎您加入噢~~希望得到建议咨询、商务合作,也请与我们联系。
分享此文一切功德,皆悉回向给文章原作者及众读者.
转自:csdn
免责声明:蓝蓝设计尊重原作者,文章的版权归原作者。如涉及版权问题,请及时与我们取得联系,我们立即更正或删除。
蓝蓝设计( www.lanlanwork.com )是一家专注而深入的界面设计公司,为期望卓越的国内外企业提供卓越的UI界面设计、BS界面设计 、 cs界面设计 、 ipad界面设计 、 包装设计 、 图标定制 、 用户体验 、交互设计、 网站建设 、平面设计服务