一、防抖
原理:当持续触发一个事件时,在n秒内,事件没有再次触发,此时才会执行回调;如果n秒内,又触发了事件,就重新进行计时。
理解:在你坐电梯时,当一直有人进电梯(连续触发),电梯门不会关闭,在一定时间间隔内没有人进入(停止连续触发)才会关闭。
使用场景:
- 输入框搜索内容,发送请求
- 频繁点击按钮,出发事件
- 监听浏览器滚动事件,完成某个特定的操作
- 用户缩放浏览器的resize事件
//1.基本实现
function debounce(fun, delay = 500){
// 定义一个定时器,保存上一次的时间
let timer = null
//真正执行的函数
const _debounce = function(){
// 取消上一次的定时器
if(timer) clearTimeout(timer)
// 延时执行
timer = setTimeout(() => {
// 外部传入的要执行的函数
fun()
},delay)
}
return _debounce
}
//2.this问题
function debounce1(fun, delay = 500){
// 定义一个定时器,保存上一次的时间
let timer = null
const _debounce = function(...args){
// 上一次的定时器存在,取消
if(timer) clearTimeout(timer)
// 延时执行
timer = setTimeout(() => {
// 外部传入的要执行的函数
fun.apply(this, args)
},delay)
}
return _debounce
}
//3.是否立即执行
function debounce(fun, delay = 500,immediate = false){
// 定义一个定时器,保存上一次的时间
let timer = null
let isInvoke = false
const _debounce = function(...args){
// 存在定时器,取消定时器
if(timer) clearTimeout(timer)
// 是否立即执行
if(immediate && !isInvoke){
fun.apply(this, args)
isInvoke = true
}else{
// 延时执行
timer = setTimeout(() => {
// 外部传入的要执行的函数
fun.apply(this, args)
isInvoke = false
},delay)
}
}
return _debounce
}
//4.添加取消
function debounce(fun, delay = 500,immediate = false){
// 定义一个定时器,保存上一次的时间
let timer = null
let isInvoke = false
const _debounce = function(...args){
// 存在定时器,取消定时器
if(timer) clearTimeout(timer)
// 是否立即执行
if(immediate && !isInvoke){
fun.apply(this, args)
isInvoke = true
}else{
// 延时执行
timer = setTimeout(() => {
// 外部传入的要执行的函数
fun.apply(this, args)
isInvoke = false
},delay)
}
}
// 取消
_debounce.cancel = function() {
if(timer) clearTimeout(timer)
timer = null
isInvoke = false
}
return _debounce
}
二、节流
原理:函数节流(throttle)是指连续触发事件,但是在n秒中只执行一次.
理解:
使用场景:
- 监听页面滚动事件
- 鼠标移动事件
- 用户频繁点击按钮事件
// 1.基本实现
function throttle (fn, interval){
let lastTime = 0
const _throttle = function(){
const newTime = new Date().getTime()
const remainTime = interval - ( newTime - lastTime)
if(remainTime<=0){
fn()
lastTime = newTime
}
}
return _throttle
}
// 2.this
function throttle1 (fn, interval){
let lastTime = 0
const _throttle = function(...args){
const newTime = new Date().getTime()
const remainTime = interval - ( newTime - lastTime)
if(remainTime<=0){
fun.apply(this, args)
lastTime = newTime
}
}
return _throttle
}
三、防抖和节流的区别、作用
- 防抖是将多次执行变为最后一次执行,节流是将多次执行变为每隔一段时间执行。
- 函数节流(throttle)与 函数防抖(debounce)都是为了限制函数的执行频次,以优化函数触发频率过高导致的响应速度跟不上触发频率,出现延迟,假死或卡顿的现象。