关注公众号, 设置为 '星标' ,更多精彩内容,第一时间获取前端
防抖与节流
导读目录
node
防抖(debounce)git
防抖应用场景github
非当即执行版web
当即执行版本浏览器
合成版本 防抖服务器
节流微信
节流应用场景app
时间戳版本编辑器
定时器版本
总结
参考
1防抖(debounce)
所谓防抖,就是指触发事件后 n 秒后才执行函数,若是在 n 秒内又触发了事件,则会从新计算函数执行时间。
防抖类型分为
非当即执行版 当即执行版 合成版本 防抖
防抖应用场景
登陆、发短信等按钮避免用户点击太快,以至于发送了屡次请求 调整浏览器窗口大小时,resize 次数过于频繁,形成计算过多,此时须要一次到位 文本编辑器实时保存,当无任何更改操做一秒后进行保存
非当即执行版
非当即执行版的意思是触发事件后函数不会当即执行,而是在 n 秒后执行,若是在 n 秒内又触发了事件,则会从新计算函数执行时间。
/**
* @description:
* @param {*} func 触发的时间
* @param {*} wait 多少时长才执行事件
* @return {*}
*/
function debounce(func, wait) {
let timeout;
return function(){
// 获取当前做用域和参数
const context = this;
const args = [...arguments]
// 若是当前timeout 存在
// 清空定时器,再次等待wait时间事后再次执行事件
if(timeout) clearTimeout(timeout)
// 定时执行 传递进来的事件
timeout = setTimeout(()=>{
func.apply(context,args)
},wait)
}
}
当即执行版本
当即执行版的意思是触发事件后函数会当即执行,而后 n 秒内不触发事件才能继续执行函数的效果。
function debounce(func,wait) {
let timeout;
return function () {
const context = this;
const args = [...arguments];
if (timeout) clearTimeout(timeout);
const callNow = !timeout;
timeout = setTimeout(() => {
timeout = null;
}, wait)
if (callNow) func.apply(context, args)
}
}
代码解析
当 执行
debounce
函数时, 第一次进来时,timeout
为false,因此callNow
的值 为true
,那么它会当即执行func
函数,这时timeout
的值 为true
, 当timeout 值为true 时
, 会执行 清空定时器,此时 timeout 又为 false 了
, 这时callNow
又 为true
,再次执行func
函数。一直循环这样的操做:
当
timeout
为false
时,会马上执行func
函数。当
timeout
为true
时,它会执行clearTimeOut
,这时timeout
又为false
, 而callNow
=! timeout
, 就会马上执行func
函数了。
合成版本 防抖
经过传递
Boolean
来决定执行哪一种版本。
true
为当即执行版false
为非当即执行版本
debounce(func,1000,true)
/**
* @desc 函数防抖
* @param func 函数
* @param wait 延迟执行毫秒数
* @param immediate true 表当即执行,false 表非当即执行
*/
function debounce(func, wait, immediate) {
let timeout;
return function () {
const context = this;
const args = [...arguments];
if (timeout) clearTimeout(timeout);
if (immediate) {
const callNow = !timeout;
timeout = setTimeout(() => {
timeout = null;
}, wait)
if (callNow) func.apply(context, args)
}
else {
timeout = setTimeout(() => {
func.apply(context, args)
}, wait);
}
}
}
2节流
所谓节流,就是指连续触发事件可是在 n 秒中只执行一次函数。 节流会稀释函数的执行频率。
节流有两种实现:
时间戳版本 定时器版本
节流应用场景
scroll
事件,每隔一秒计算一次位置信息等浏览器播放事件,每一个一秒计算一次进度信息等 input
输入框在搜索内容时,能够控制多少s 在执行请求,避免屡次发起请求,节约性能。
时间戳版本
function throttle(func, wait) {
var previous = 0;
return function() {
let now = Date.now();
let context = this;
let args = arguments;
if (now - previous > wait) {
func.apply(context, args);
previous = now;
}
}
}
定时器版本
function throttle(func, wait) {
let timeout;
return function() {
let context = this;
let args = arguments;
if (!timeout) {
timeout = setTimeout(() => {
timeout = null;
func.apply(context, args)
}, wait)
}
}
}
代码解析
当执行
throttle
函数时,timeout
默认为undefined
, 此时,! timeout
为true
时,执行 定时器,而且 将timeout
为 null,即为false
, 再次执行throttle
函数时,!timeout
又为true
,再次执行定时器。**经过
timeout
的状态来达到节流的控制 **
3总结
防抖:触发事件后,必定时间后再执行事件,能够
当即执行
也能够必定时间再执行
节流:控制流量,在单位时间内只能请求一次,避免屡次触发事件,影响服务器性能。
参考
https://github.com/mqyqingfeng/Blog/issues/26
原创不易,素质三连
本文分享自微信公众号 - 前端自学社区(gh_ce69e7dba7b5)。
若有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一块儿分享。