防抖(debounce)、节流(throttle)
相同点:两种技术都是为了减少频繁操作
不同点:防抖是在频繁操作后只进行最后一次操作,常用于表单的提交,频繁的点赞,这样避免了多次提交,只会提交一次请求,减少了服务器的压力。
节流是每隔一段固定的时间触发一次请求,在间隔时间内的操作不会产生操作,常用于页面滚动,页面缩放进行一些操作。比如图片或者长列表的懒加载的操作。
代码实现防抖
主要思路利用延迟函数来实现
先清除延迟=>再设置延迟函数=>延迟函数内部执行我们需要的操作
如果点击后延迟时间到了则执行延迟函数内部的操作,如果没有等到延迟时间操作的话就会清除延迟。
let debonce = function (fn, delay) {
let timer
return function () {
// 清除延迟
clearTimeout(timer)
let _this = this
// 设置延迟
timer = setTimeout(() => {
// 修复this指向 执行fn
fn.call(_this)
},delay)
}
}
代码实现节流
思路一: 利用延迟函数
判断是否能进延迟函数=>设置延迟函数 => 进入延迟的同时阻止下次进入延迟函数=>延迟函数内部执行我们需要的操作,并允许进入延迟
基础版
let throttle = function (fn, delay) {
let flag = true
let _this = this
let timer
return function () {
// 判断是否能进延迟函数
if (flag) {
// 设置延迟函数
timer = setTimeout(()=>{
// 修复this
fn.call(_this)
// 允许进入延迟
flag = true
},delay)
// 进入延迟的同时阻止下次进入延迟函数
flag = false
}
}
}
优化版
基础版引入了一个falg变量来作为判断条件,我们可以只用timer来判断
let throttle = function (fn, delay) {
let timer
let context = this
return function () {
if (!timer) {
timer = setTimeout(() => {
fn.call(context)
timer = null
}, delay)
}
}
}
思路二:利用date对象
将当前时间和上一次执行时间分别保存起来,如果当前时间减去上一次执行的时间大于设置的延迟就执行我们的操作,并将上次执行时间重新赋值。
let throttle = function (fn, delay) {
let lastTime = 0
let nowTime = 0
let _this = this
return function () {
nowTime = new Date()
if (nowTime - lastTime > delay) {
fn.call(_this)
lastTime = nowTime
}
}
}